寫在前面
強快取和協商快取是 Web 快取機制的重要組成部分,它們在最佳化 Web 應用效能方面發揮了重要作用,接下來我們就來詳細的聊一下吧!
強快取
概念
強快取指的是在快取有效期內,不需要向伺服器傳送請求,直接從快取中讀取資源。這意味著在快取有效期內,瀏覽器直接使用快取的資源,不會與伺服器通訊。
好處
減少伺服器負載:減少了不必要的請求,伺服器負載顯著降低。
提高頁面載入速度:資源直接從本地快取中讀取,減少了網路延遲,頁面載入速度更快。
節省頻寬:避免重複下載相同的資源,節省了頻寬資源。
改善使用者體驗:快速的頁面載入提高了使用者滿意度和留存率。
如何開啟
強快取主要透過 HTTP 響應頭中的 Expires
和 Cache-Control
屬性來實現。這些屬性是由伺服器在響應中設定的,並指示瀏覽器如何快取資源。
詳細說明
Expires
定義:一個絕對時間點,在此時間點之前,快取的資源被認為是有效的。
位置:響應頭
例子:
Expires: Wed, 21 Oct 2024 07:28:00 GMT
Cache-Control
定義:更現代、更靈活的快取控制方式,可以定義更細粒度的快取策略。
位置:響應頭
常用指令:
max-age
:相對時間,以秒為單位。例如:Cache-Control: max-age=3600
表示資源可以快取 3600 秒(1 小時)。
no-cache
:不使用強快取,每次都要向伺服器傳送請求以確認資源是否改變。
no-store
:不快取資源,完全禁用快取。
public
:表示響應可以被任何快取儲存(包括瀏覽器和中間代理伺服器)。
private
:表示響應只能被單個使用者的瀏覽器快取,不允許代理快取。
協商快取
概念
協商快取需要客戶端和伺服器之間的互動。當快取資源過期時,客戶端會向伺服器傳送請求,伺服器根據請求頭中的資訊判斷客戶端快取的資源是否仍然有效。
好處
節省頻寬:對於未修改的資源,伺服器只返回狀態碼而不傳送資源內容,節省了頻寬。
減少延遲:即使需要與伺服器通訊,304 響應也比完全下載新的資源更快。
保持資源最新:確保瀏覽器使用的是最新版本的資源,提高了資料的一致性和可靠性。
平衡效能與新鮮度:在減少不必要請求的同時,確保資源的實時更新。
如何開啟
協商快取使用的主要屬性是伺服器返回的 Last-Modified
和 ETag
,而在下次請求時會使用 If-Modified-Since
和 If-None-Match
, 它們的值在實現協商快取時起著關鍵作用。
詳細說明
協商快取相關屬性:
Last-Modified:(伺服器響應)
含義: 資源的最後修改時間。
格式: 一個 GMT 格式的時間字串。
示例:
Last-Modified: Mon, 06 May 2024 15:29:24 GMT
備註:和
If-Modified-Since
配合使用
If-Modified-Since:(請求頭攜帶)
含義: 客戶端傳送的請求頭,其值通常是上次請求時伺服器返回的 Last-Modified 值。
用途: 伺服器根據這個值判斷資源是否有更新。
ETag:(伺服器響應)
含義: 資源的唯一識別符號,通常是資源內容的雜湊值或版本號。
示例:
ETag: "vXLkk8K9CFhdG97yneeeSdE6ow4=
備註:和
If-None-Match
配合使用
If-None-Match: (請求頭攜帶,優先順序更高)
含義: 客戶端傳送的請求頭,其值通常是上次請求時伺服器返回的 ETag 值。
用途: 伺服器根據這個值判斷資源是否有更新。
協商快取的工作流程
首次請求:瀏覽器請求資源,伺服器返回資源內容以及 Last-Modified
和/或 ETag
。
Last-Modified: Mon, 06 May 2024 15:29:24 GMT ETag: "vXLkk8K9CFhdG97yneeeSdE6ow4="
後續請求:瀏覽器再次請求該資源時,會帶上 If-Modified-Since
和/或 If-None-Match
請求頭。(當資源被快取後,瀏覽器會根據之前伺服器響應中的快取頭資訊,在後續請求中自動新增這些請求頭,以實現協商快取機制。)
If-Modified-Since: Mon, 06 May 2024 15:29:24 GMT If-None-Match: "vXLkk8K9CFhdG97yneeeSdE6ow4="
伺服器響應:如果資源未修改,伺服器返回 304 Not Modified 狀態碼,不包含訊息體,瀏覽器繼續使用快取資源。
如果資源已修改,伺服器返回 200 OK 狀態碼和新的資源內容,同時更新 Last-Modified
和/或 ETag
。
優先順序
伺服器首先會檢查
If-None-Match
中的ETag
值是否與伺服器上該資源的當前 ETag 值匹配。如果 ETag 匹配成功(即資源內容未發生變化),伺服器會返回 304 Not Modified 狀態碼,並結束響應,不再檢查
Last-Modified
。如果ETag匹配失敗(即資源內容可能發生變化),伺服器會繼續檢查
If-Modified-Since
中的Last-Modified
值(這提供了一個"雙重檢查"的機制,有助於在各種情況下最佳化資源傳輸)。ETag 的優先順序
高於
Last-Modified。這是因為 ETag 是基於資源內容生成的唯一識別符號,能夠更加準確地反映資源是否發生變化。而 Last-Modified 只是記錄了資源最後修改的時間戳,可能會因為某些原因(如伺服器時間設定不準確、檔案被定期生成但內容未變等)而導致不準確。
綜合對比
特性/機 制 | 強快取 | 協商快取 |
---|---|---|
定義 | 瀏覽器直接從快取中讀取資源,無需與伺服器通訊 | 瀏覽器向伺服器驗證快取資源的有效性 |
實現方式 | HTTP 頭資訊中的 Expires 和 Cache-Control |
HTTP 頭資訊中的 Last-Modified 和 ETag |
響應頭 | Expires , Cache-Control |
ETag , Last-Modified |
請求頭 | 無需特定請求頭 | If-None-Match , If-Modified-Since |
匹配優先順序 | 無 | ETag 優先順序高於 Last-Modified |
匹配原理 | 根據快取有效期直接使用快取 | 瀏覽器傳送上次接收的 ETag 或 Last-Modified ,伺服器比較並返回 304 或 200 |
處理流程 | 瀏覽器檢查快取有效期,若有效直接使用 | 瀏覽器請求資源時,傳送 If-None-Match 和 If-Modified-Since ,伺服器根據 ETag 和 Last-Modified 判斷是否返回 304 或 200 |
典型場景 | 靜態資源如圖片、CSS、JS 檔案 | 動態資源或頻繁更新的資源 |
快取控制 | 由瀏覽器控制,依賴於快取策略和有效期 | 由伺服器控制,透過生成和驗證 ETag 和 Last-Modified 實現 |
優先順序處理 | 不涉及優先順序 | 伺服器優先檢查 If-None-Match ,ETag 不匹配時直接返回 200,不再檢查 If-Modified-Since |
資源變化檢測 | 依賴於快取時間,不檢測內容變化 | 基於內容 (ETag ) 或修改時間 (Last-Modified ) 檢測資源變化 |
快取策略 | 透過設定快取有效期控制 | 透過伺服器和瀏覽器間的快取驗證控制 |
優勢 | 減少網路請求,提升載入速度 | 確保資源最新狀態,節省頻寬 |
劣勢 | 可能使用過期的快取,無法實時更新 | 增加請求開銷,需要伺服器支援 |