問題描述
最近對文件上傳功能進行了優化改版,上線之後有同事反饋出來,自從上線之後所上傳的圖片,均沒有設置瀏覽器端緩存,導致客户端每次都要去請求服務器上的圖片資源,會導致頁面加載速度變慢,用户體驗不好諸類問題。之前從未接觸過此類問題趕忙查閲了瀏覽器緩存的相關知識,並對問題進行了修復,現將一些所學進行整理歸納。
HTTP的緩存機制
在Chrom瀏覽器中打開一張圖片,比如華為新款P30手機,選擇一張圖片(https://res9.vmallres.com/shopdc/pic/e769ea22-d741-45fd-94e8-1b39deb19719.jpg),查看它的網絡請求信息。
第一次請求
第二次請求
強緩存
可以理解為無須驗證的緩存策略。對強緩存來説,響應頭中有兩個字段 Expires/Cache-Control 來表明規則。
Expires
Expires 指緩存過期的時間,超過了這個時間點就代表資源過期。有一個問題是由於使用具體時間,如果時間表示出錯或者沒有轉換到正確的時區都可能造成緩存生命週期出錯。
Cache-Control
Cache-Control 可以由多個字段組合而成,主要有以下幾個取值:
Cache-Control: max-age =? : 指定一個時間長度,在這個時間段內緩存是有效的,單位是s。例如設置 Cache-Control:max-age=31536000,也就是説緩存有效期為(31536000 / 24 / 60 * 60)天。
Cache-Control: no-cache強制所有緩存了該響應的用户,在使用已緩存的數據前,發送帶驗證器的請求到服務器。不是字面意思上的不緩存。
Cache-Control: no-store才是真正的不緩存數據到本地
Cache-Control: public可以被所有用户緩存(多用户共享),包括終端和CDN等中間代理服務器
Cache-Control: private只能被終端瀏覽器緩存(而且是私有緩存),不允許中繼緩存服務器進行緩存
協商緩存
緩存的資源到期了,並不意味着資源內容發生了改變,如果和服務器上的資源沒有差異,實際上沒有必要再次請求。客户端和服務器端通過某種驗證機制驗證當前請求資源是否可以使用緩存。
瀏覽器第一次請求數據之後會將數據和響應頭部的緩存標識存儲起來。再次請求時會帶上存儲的頭部字段,服務器端驗證是否可用。如果返回 304 Not Modified,代表資源沒有發生改變可以使用緩存的數據,獲取新的過期時間。反之返回 200 就相當於重新請求了一遍資源並替換舊資源。
Last-Modified與If-Modified-Since
Last-modified: 服務器端資源的最後修改時間,響應頭部會帶上這個標識。第一次請求之後,瀏覽器記錄這個時間,再次請求時,請求頭部帶上 If-Modified-Since 即為之前記錄下的時間。服務器端收到帶 If-Modified-Since 的請求後會去和資源的最後修改時間對比。若修改過就返回最新資源,狀態碼 200,若沒有修改過則返回 304。
ETag與If-None-Match
由服務器端上生成的一段 hash 字符串,第一次請求時響應頭帶上 ETag: abcd,之後的請求中帶上 If-None-Match: abcd,服務器檢查 ETag,返回 304 或 200。
緩存流程
用户行為與緩存的使用方式
參考資料:
https://zhuanlan.zhihu.com/p/29750583