http快取策略以及強快取和協商快取淺析

程式設計師布歐發表於2022-05-12

http快取策略以及強快取和協商快取淺析

本地快取-強快取

本地快取,也就是我們常說的強快取:是指當瀏覽器請求資源時,如果請求服務端的資源命中了瀏覽器本地的快取資源,那麼瀏覽器就不會傳送真正請求給伺服器。
此時的請求過程:

第一次請求

  • 當瀏覽器還是第一次傳送請求到後端的時候,本地還沒有快取資源,這個時候的伺服器返回給瀏覽器的資源,響應碼是200
  • 當瀏覽器收到資源後,會將資源和對應的響應頭一起快取下來。

第二次請求

  • 第二次瀏覽器準備傳送請求給伺服器時候,瀏覽器會先檢查上一次服務端返回的響應頭資訊中的Cache-Control(它的值是一個相對值,單位為秒,表示資源在客戶端快取的最大有效期)
  • 過期時間為第一次請求的時間加上Cache-Control的值,
  • 過期時間跟當前的請求時間比較,如果本地快取資源沒過期,那麼命中快取,不再請求伺服器。
    • 如果沒有命中,瀏覽器就會把請求傳送給伺服器,進入快取協商階段。

快取協商

場景1

  • 當客戶端瀏覽器第一次請求的時候,分為兩種情況:
    • 第一種:伺服器端返回的響應頭中沒有Cache-Control和Expires或者Cache-Control和Expires
    • 第二種:Cache-Control的屬性設定為no-cache時

場景2

  • 瀏覽器第二次請求時就會與伺服器進行協商,對比瀏覽器中的快取資源,是否是最新的。
  • 當快取和服務端資源的最新版本是一致的,那麼就無需再次下載該資源,服務端直接返回重定向304 Not Modified 狀態碼,
  • 如果伺服器發現瀏覽器中的快取已經是舊版本了,那麼伺服器就會把最新資源的完整內容返回給瀏覽器,狀態碼就是200
  • 服務端是根據HTTP的另外兩組頭資訊,分別是:Last-Modified/If-Modified-Since 與 ETag/If-None-Match,這兩組資料一 一對應,互相結合使用

http快取策略淺析


本地快取-強快取相關欄位解析

Cache-control 快取頭部

Cache-Control、Expires,Cache-Control有多個可選值代表不同的意義,而Expires就是一個日期格式的絕對值。

  • Cache-Control是HTTP快取策略中最重要的頭資訊,它是HTTP/1.1中出現的
  • Cache-Control 頭用來區分對快取機制的支援情況, 請求頭和響應頭都支援這個屬性。通過它提供的不同的值來定義快取策略

沒有快取

快取中不得儲存任何關於客戶端請求和服務端響應的內容。每次由客戶端發起的請求都會下載完整的響應內容。

Cache-Control: no-store


快取但重新驗證

如下頭部定義,此方式下,每次有請求發出時,快取會將此請求發到伺服器(譯者注:該請求應該會帶有與本地快取相關的驗證欄位),伺服器端會驗證請求中所描述的快取是否過期,若未過期(注:實際就是返回304),則快取才使用本地快取副本。

Cache-Control: no-cache


私有和公共快取

"public" 指令表示該響應可以被任何中間人(譯者注:比如中間代理、CDN等)快取。若指定了"public",則一些通常不被中間人快取的頁面(譯者注:因為預設是private)(比如 帶有HTTP驗證資訊(帳號密碼)的頁面 或 某些特定狀態碼的頁面),將會被其快取。

而 "private" 則表示該響應是專用於某單個使用者的,中間人不能快取此響應,該響應只能應用於瀏覽器私有快取中。

Cache-Control: private
Cache-Control: public


過期

過期機制中,最重要的指令是 "max-age=",表示資源能夠被快取(保持新鮮)的最大時間。相對Expires而言,max-age是距離請求發起的時間的秒數。針對應用中那些不會改變的檔案,通常可以手動設定一定的時長以保證快取有效,例如圖片、css、js等靜態資源。

詳情看下文關於快取有效性的內容。

Cache-Control: max-age=31536000

驗證方式

當使用了 "must-revalidate" 指令,那就意味著快取在考慮使用一個陳舊的資源時,必須先驗證它的狀態,已過期的快取將不被使用。詳情看下文關於快取校驗的內容。

Cache-Control: must-revalidate


Expires

Expires是HTTP/1.0出現的頭資訊,同樣是用於決定本地快取策略的頭,它是一個絕對時間,時間格式是如Mon, 10 Jun 2015 21:31:12 GMT,只要傳送請求時間是在Expires之前,那麼本地快取始終有效,否則就會去伺服器傳送請求獲取新的資源。如果同時出現Cache-Control:max-age和Expires,那麼max-age優先順序更高。
Cache-Control與Expires可以在服務端配置同時啟用,同時啟用的時候Cache-Control優先順序高

兩者結合使用:


cache-control:max-age=691200
expires:Fri, 06 Mar 2022 22:53:02 GMT


快取驗證

使用者點選重新整理按鈕時會開始快取驗證。如果快取的響應頭資訊裡含有"Cache-control: must-revalidate”的定義,在瀏覽的過程中也會觸發快取驗證。另外,在瀏覽器偏好設定裡設定Advanced->Cache為強制驗證快取也能達到相同的效果。

當快取的文件過期後,需要進行快取驗證或者重新獲取資源。只有在伺服器返回強校驗器或者弱校驗器時才會進行驗證。

協商快取相關欄位概念

ETags

  • Etag的優先順序高於Last-Modified
  • 作為快取的一種強校驗器,ETag 響應頭是一個對使用者代理(User Agent, 下面簡稱UA)不透明(注:UA無需理解,只需要按規定使用即可)的值。
  • 對於像瀏覽器這樣的HTTP UA,不知道ETag代表什麼,不能預測它的值是多少。如果資源請求的響應頭裡含有ETag, 客戶端可以在後續的請求的頭中帶上 If-None-Match 頭來驗證快取。

Last-Modified

  • Last-Modified 響應頭可以作為一種弱校驗器。說它弱是因為它只能精確到一秒。如果響應頭裡含有這個資訊,客戶端可以在後續的請求中帶上 If-Modified-Since 來驗證快取。

  • 其中包含源頭伺服器認定的資源做出修改的日期及時間。 它通常被用作一個驗證器來判斷接收到的或者儲存的資源是否彼此一致。由於精確度比 ETag 要低,所以這是一個備用機制

  • 當向服務端發起快取校驗的請求時,服務端會返回 200 ok表示返回正常的結果或者 304 Not Modified(不返回body)表示瀏覽器可以使用本地快取檔案。304的響應頭也可以同時更新快取文件的過期時間。

HTTP 響應頭決定了對於後續的請求頭,如何判斷是請求一個新的資源還是使用快取的檔案。

Vary

  • Vary是一個HTTP響應頭部資訊,它決定了對於未來的一個請求頭,應該用一個快取的回覆(response)還是向源伺服器請求一個新的回覆。它被伺服器用來表明在 content negotiation algorithm(內容協商演算法)中選擇一個資源代表的時候應該使用哪些頭部資訊(headers).

  • 在響應狀態碼為 304 Not Modified 的響應中,也要設定 Vary 首部,而且要與相應的 200 OK 響應設定得一模一樣。

  • 當快取伺服器收到一個請求,只有當前的請求和原始(快取)的請求頭跟快取的響應頭裡的Vary都匹配,才能使用快取的響應。

  • 使用vary頭有利於內容服務的動態多樣性。例如,使用Vary: User-Agent頭,快取伺服器需要通過UA判斷是否使用快取的頁面。如果需要區分移動端和桌面端的展示內容,利用這種方式就能避免在不同的終端展示錯誤的佈局。另外,它可以幫助 Google 或者其他搜尋引擎更好地發現頁面的移動版本,並且告訴搜尋引擎沒有引入Cloaking。

Vary: User-Agent
因為移動版和桌面的客戶端的請求頭中的User-Agent不同, 快取伺服器不會錯誤地把移動端的內容輸出到桌面端到使用者。


瀏覽器快取的優缺點

缺點

  • 正如字面意思,快取,就意味著使用快取的時候,伺服器的資源有可能不是最新版本,這就需要在使用的時候,控制快取的資源和時間,包括常見的CDN手段。

優點

  • 使用瀏覽器客戶端快取能夠減少請求的時間,提高使用者體檢,提高頁面響應時間。

  • 在前端優化的手段當中,減少http請求的方式,也是其中一種,有效使用快取,可以減少伺服器的壓力,提升網站的效能。


歡迎關注公眾號:程式設計師布歐,不定期更新技術入門文章

創作不易,轉載請註明出處和作者。

相關文章