藉由使用之前已取用過的資料,加速網站讀取,減少與server的請求,提升效能。
當一個網頁需要的資源越來越多,大小越來越大,如果沒有快取機制,那每次載入時,所有的資源都要重新向 server 請求,那這樣其實會拖慢效能,使用者體驗也會不好,因此這時快取就變得猶為重要。
http cache 的行為是由 request headers 和 response headers 控制。前端能控制的是request header,response headers則由後端控制。
檔頭介紹
Pragma : HTTP/1.0 用來定議快取機制,能設定為no-cache,與cache-control的no-cache相同。
Expires : HTTP/1.0 定議過期時間。
—
* request headers 和 response headers 皆有
Cache-Control : 是HTTP/1.1 用來定議快取機制。
- no-store 不要任何快取
- no-cache 在cache把複製版本給user前,會先向server做驗證。
- private 只有私有快取能存取
- public 私有、共用皆可取
- max-age 能維持多久,存取時間不能大於此值,超過就向server重新請求。
- must-revalidate 一定要先向server驗證
- stale-while-revalidate 當我們向server請求時,客戶可先使用過期的檔案,等重新驗證完後,下次使用的就為新的。
—
* 只存在 response headers。
Last-Modified & If-Modified-Since : 檔案最後的修改時間,每次請求皆會一同返回給客戶端。依此確認檔案是否被修改過。時間一致等於沒改變,回傳時會返回 304 「 Status code: 304 (Not Modified) 」,不同則表示更改過。另外當快取過期後,就可以利用這個資訊,改用 If-Modified-Since 來跟 server 拿取某個時間點後有更改的檔案。
不過 Last-Modified 有時是不準確的,像是可能檔案是被重新編輯過,但實際內容沒有任何改變,這時卻會因為Last-Modified時間不同,而被認為是不同的,再次回傳整個檔案給user。那如何解決呢?下個檔頭說明。
ETag & If-None-Match : 為了解決上述 Last-Modified 存在的不準確問題。
簡單來說,ETag 為 server 計算出來的 hash 值,就像 md5 一樣,它是根據內容產生出來的,因此可以用來判斷資源是否被更改過。如此一來,就不會出現 Last-Modified 的不準確問題。
If-None-Match,就像 Last-Modified 和 If-Modified-Since 一樣。快取過期後,瀏覽器會發送 If-None-Match 向 server 確認是否有新檔案,有的話回傳新的,沒有則回傳 304「 Status code: 304 (Not Modified) 」。
小結
前端能做的除了request headers,再來就我所知,就是幫各檔案的名字加上 hash 碼而已,而如何做,則可以透過 webpack bundle 加上,如果以 vue 來說用 vue-cli 時它也幫我們處理完畢了,所以我覺得前端能控制的有限,主要還是需要與後端的合作配合。