瀏覽器緩存整理

對瀏覽器緩存這一塊一直是亂哄哄的狀態,今天終於有時間整理一下,寫下這篇筆記,以供往後查閱。git

緩存概述

良好的緩存策略能夠下降資源的重複加載提升網頁的總體加載速度
一般瀏覽器緩存策略分爲兩種:強緩存和協商緩存github

基本流程

  1. 瀏覽器在加載資源時,根據請求頭的expires和cache-control判斷是否命中強緩存,是則直接從緩存讀取資源,不會發請求到服務器。
  2. 若是沒有命中強緩存,瀏覽器必定會發送一個請求到服務器,經過last-modified和etag驗證資源是否命中協商緩存,若是命中,服務器會將這個請求返回,可是不會返回這個資源的數據,依然是從緩存中讀取資源
  3. 若是前面二者都沒有命中,直接從服務器加載資源

相同點

若是命中,都是從客戶端緩存中加載資源,而不是從服務器加載資源數據;web

不一樣點

強緩存不發請求到服務器,協商緩存會發請求到服務器。segmentfault

強緩存

強緩存經過ExpiresCache-Control兩種響應頭實現瀏覽器

Expires

Expires是http1.0提出的一個表示資源過時時間的header,它描述的是一個絕對時間,由服務器返回。
Expires 受限於本地時間,若是修改了本地時間,可能會形成緩存失效緩存

Expires: Sat, 29 Sep 2018 14:20:00 GMT

Cache-Control

Cache-Control 出現於 HTTP / 1.1,優先級高於 Expires ,表示的是相對時間服務器

Cache-Control: max-age=315360000

Cache-Control在request和response中均可以使用負載均衡

  1. 在請求中使用Cache-Control 時,它可選的值有:

Cache-Control在請求頭中的取值

  1. 在響應中使用Cache-Control 時,它可選的值有:

Cache-Control在響應頭中的取值

強緩存流程圖

強緩存流程圖

協商緩存

當瀏覽器對某個資源的請求沒有命中強緩存,就會發一個請求到服務器,驗證協商緩存是否命中,若是協商緩存命中,請求響應返回的http狀態爲304而且會顯示一個Not Modified的字符串分佈式

協商緩存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】這兩對Header來管理的google

Last-Modified,If-Modified-Since

Last-Modified 表示請求來的文件的最後修改日期,瀏覽器會在request header加上If-Modified-Since(上次返回的Last-Modified的值),詢問服務器在該日期後資源是否有更新,有更新的話就會將新的資源發送回來。

ETag、If-None-Match

Etag就像一個指紋,資源變化都會致使ETag變化,跟最後修改時間沒有關係,ETag能夠保證每個資源是惟一的

If-None-Match的header會將上次返回的Etag發送給服務器,詢問該資源的Etag是否有更新,有變更就會發送新的資源回來

ETag的優先級比Last-Modified更高

大體流程

  1. 客戶端請求一個頁面(A)。
  2. 服務器返回頁面A,並在給A加上一個Last-Modified/ETag。
  3. 客戶端展示該頁面,並將頁面連同Last-Modified/ETag一塊兒緩存。
  4. 客戶再次請求頁面A,並將上次請求時服務器返回的Last-Modified/ETag一塊兒傳遞給服務器。
  5. 服務器檢查該Last-Modified或ETag,並判斷出該頁面自上次客戶端請求以後還未被修改,直接返回響應304和一個空的響應體。

感受兩個功能重複了?

ETag對Last-Modified的補充

首先Last-Modified在http/1.0中被提出,而在http/1.1中提出的ETag則是爲了解決Last-Modified沒法解決的一些問題

  1. 一些文件也許會週期性的更改,可是他的內容並不改變(僅僅改變的修改時間),這個時候咱們並不但願客戶端認爲這個文件被修改了,而從新GET;
  2. 某些文件修改很是頻繁,好比在秒如下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改沒法判斷(或者說UNIX記錄MTIME只能精確到秒);
  3. 某些服務器不能精確的獲得文件的最後修改時間。

Last-Modified對ETag的補充

一些圖片等靜態文件的修改,若是每次掃描內容生成 ETag 來比較,顯然要比直接比較修改時間慢不少

小結

因此說二者並非互斥,而是相輔相成的關係,既能夠單獨使用,又能夠同時使用。

同時傳入服務器時,服務器能夠根據本身的緩存機制的須要,選擇ETag或者是Last-Modified來作緩存判斷的依據,甚至能夠兩個同時參考。

如何使用

協商緩存須要配合強緩存使用,若是不啓用強緩存的話,協商緩存根本沒有意義

大部分web服務器都默認開啓協商緩存,並且是同時啓用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】

Apache對於靜態內容默認會返回Last-modified和ETag.

Nginx只會返回Last-modified(可配置etag on開啓).

可是下面的場景須要注意:

  • 分佈式系統裏多臺機器間文件的Last-Modified必須保持一致,以避免負載均衡到不一樣機器致使比對失敗;
  • 分佈式系統儘可能關閉掉ETag(每臺機器生成的ETag都會不同)

總體流程圖

瀏覽器緩存整理

參考

https://github.com/amandakela...
https://blog.csdn.net/u012375...
https://segmentfault.com/q/10...
baidu and google

原文在這裏

相關文章
相關標籤/搜索