[note] HTTP Cache 快取
TL;DR
- 透過 HTTP Cache 是避免瀏覽器向伺服器發送不必要請求的第一道防線,一般來說我們只需要用到
cache-control
(做 cache) 和etag
(做 revalidate)。 - 瀏覽器自行判斷:
Cache-Control: max-age=...
的用法有機會讓瀏覽器完全不送出請求 - 搭配伺服器判斷:
Last-Modified
和eTag
的使用則會在瀏覽器產生對應的If-Modified-Since
和If-None-Match
標頭,伺服器在根據此標頭判斷是否要回傳新的檔案,或回傳304 Not Modified
即可。 - 使用
Cache-Control: no-store
瀏覽器將不會快取任何內容(永遠不要快取)。 - 使用
Cache-Control: no-cache
瀏覽器會快取所有內容,但每次都會發送請求向伺服器詢問是否有新內容要提供(永遠檢查快取)。
圖片來源:Prevent unnecessary network requests with the HTTP Cache
重要名詞與概念
Cache
- 在不需要檢查有沒有更新的情況下,瀏覽器可以重複使用這個回應多久
- Cache 是避免 client 和 sever 提出請求的一種方式
cache-control
針對的就是 cache
Revalidate
- 當快取過期後,要如何確認這個 response 有沒有新的版本( ⚠️ 也就是說,如果 cache 沒有過期,就沒有所謂 revalidate 的問題)
- 如果 cache 沒有過期,revalidation 是不會發生的
etag
針對的就是 revalidate- 邏輯上來說,即使沒有做 revalidate 的動作也不會怎麼樣,頂多就是重新 fetch 一次檔案,但因為這個檔案有可能是一樣的,所以如果不做 revalidate 的話,就可能會浪費了傳輸的流量
- 內容不會改變的檔案,完全不需要 revalidate
Fresh & Stale
當 response 已經在 cache 中後:
- fresh:只能表示 cache 還沒過期,⚠️ 但並不表示 response 是最新的
- stale:cache 已經過期
HTTP Status Code
對應到 Server 回應的 HTTP Status Code:
- 200(OK):只是表示成功得到了一個完整的 response,這個 response 有可能從 server 來,但也有可能從 browser cache 來(⚠️ 無法從
200
判斷瀏覽器是否用了 cache) - 304(Not Modified):server 檢查後向瀏覽器表示可以繼續使用原本 cache 中的 response,通常會發生在 cache stale 後,向 server 訊問後得到的回應。
Cache 運作的原理
所有透過瀏覽器發送的 HTTP 請求,都會先經過瀏覽器的快取,在這裡會先檢查是否有有效的快取內容可作為回應,如果有的話就直接讀取快取的內容,以減少網路的延遲和傳輸造成的成本。
一般來說,瀏覽器會在發送請求的時候自動選擇最適合的快取方式,因此即使你不去設定 Cache-Control
的 header,瀏覽器依然會選擇最適合的方式。
在判斷資源有沒有過期時,會先看 Cache-Control: max-age="..."
,沒有的話才會去看 Expires
;如果沒有 max-age
也沒有 Expires
的話,才會再進一步去看 Last-modified
。