資源緩存用于緩存靜態資源,良好的緩存策略可以減少資源重復加載進而提高網頁的整體加載速度。
通常瀏覽器緩存策略分為兩種:強緩存和協商緩存,當然還包括 service worker。
-
瀏覽器在資源加載時,根據請求頭中的 expires 和 cache-control 值來判斷是否命中強緩存,命中則直接從本地緩存中讀取資源,這一過程不需請求服務器。
-
如果未命中強緩存,瀏覽器則會發送請求到服務器,服務器通過 last-modified 和 etag 值來驗證資源是否命中協商緩存,若命中,則服務器會將這個請求返回,但是不會返回這個資源的數據,瀏覽器接收到該請求響應后依然從本地緩存中讀取資源。
-
若強緩存和策略緩存都未命中,那么瀏覽器將請求服務器獲得資源并加載。
強緩存和策略緩存如果命中,都是直接從客戶端緩存加載對應資源。但不同點是:強緩存自比較開始至緩存命中不會請求服務端,而策略緩存的是否使用本地緩存這一決定是需要服務端參與的,換言之策略緩存需要請求服務端來完成的。
1. 強緩存
強緩存通過 Expires 和 Cache-Control 響應頭實現。兩者詳細說明如下:
1.1. Expires
中文釋義為:到期,表示緩存的過期時間。expire 是 HTTP 1.0 提出的,它描述的是一個絕對時間,該時間由服務端返回。因為 expire 值是一個固定時間,因此會受本地時間的影響,如果在緩存期間我們修改了本地時間,可能會導致緩存失效。
通常表示如下:
Expires: Wed, 11 May 2018 07:20:00 GMT
1.2. Cache-Control
中文釋義為:緩存控制。cache-control 是 HTTP 1.1 提出的,它描述的是一個相對時間,該相對時間由服務端返回。
通常表示如下:
Cache-Control: max-age=315360000
該屬性還包括訪問性及緩存方式設置,列舉如下:
-
no-cache 存儲在本地緩存取中,只是在與服務器進行新鮮度再驗證之前,緩存無法使用。
-
no-store 不緩存資源到本地。
-
public 可被所有用戶緩存,多用戶進行共享,包括終端或 CDN 等中間代理服務器。
-
private 僅能被瀏覽器客戶端緩存,屬于私有緩存,不允許中間代理服務器緩存相關資源。
緩存與使用緩存流程說明如下:
2. 協商緩存
瀏覽器加載資源時,若強緩存未命中,將發送資源請求至服務器。若協商緩存命中,請求響應返回304狀態碼。
協商緩存主要使用到兩對請求響應頭字段,分別是:
-
Last-Modified 和 If-Modified-Since
-
Etag 和 If-None-Match
2.1. Last-Modified 與 If-Modified-Since
Last-Modified 由上一次請求的響應頭返回,且該值會在本次請求中,通過請求頭If-Modified-Since傳遞給服務端,服務端通過 If-Modified-Since與資源的修改時間進行對比,若在此日期后資源有更新,則將新的資源發送給客戶端。
不過,通過文件的修改時間來判斷資源是否更新是不明智的,因為很多時候文件更新時間變了,但文件內容未發生更改。
這樣一來,就出現了 ETag 與 If-None-Match。