掘金上有很多講快取講得很精彩很透徹的文章,我這篇文章重在個人的學習吧,希望儘量能往老瓶裡面裝點新酒。好吧,廢話不多說,馬上進入主題。
眾所周知,快取分為兩種。一種是強快取,另外一種是協商快取。如果命中強快取,那麼瀏覽器將不需要請求伺服器直接拿快取資源來使用。而協商快取不管是否命中都要和伺服器端發生互動的。因此在實際開發中,是希望更多的命中強快取的,因為這樣可以減少對伺服器的請求,效能無疑會更好。
快取匹配流程圖:
強快取
由上面的圖可以看出來,強快取的優先順序是要比協商快取高的。而控制強快取的有兩個http頭欄位控制。
- Expires
它是一個HTTP 1.0版本的一個HTTP頭欄位,用於宣告快取的過期時間。但是由於它記錄的是一個絕對的時間,這就很可能會因為時區或者時間格式等問題導致快取失效。因此現在在實際開發中基本已經很少使用了。
- Cache-Control
Cache-Control是一個HTTP 1.1版本的HTTP頭欄位。它的優先順序會比Expires高,當二者同時存在時,瀏覽器會以Cache-Control作為快取是否過期的依據。
值得注意的是no-cache並不是說不快取,而是指每次請求都必須先請求一下伺服器,其實跟協商快取很類似。而真正的不快取是no-store.另外一個常用的欄位就是max-age.max-age表示快取的內容在XXX秒內有效,這就可以很好的解決了Expires由於地區和格式引起的問題。
協商快取
協商快取等於每次瀏覽器請求資源之前都會先發一個請求給伺服器檢視資源是否有更改,如果資源沒有更改即使資源過期了,瀏覽器照樣可以拿快取的內容來使用。可以說是一種更安全的快取方案。
- Last-modified/If-Modified-Since
Last-modified表示資源最後修改的時間,響應頭會帶上這個標識。當瀏覽器瀏覽器請求完這個資源之後就會把這個時間記錄下來。再次請求時,請求頭會帶上If-Modified-Since 的欄位,伺服器端收到後,就會根據If-Modified-Since的時間與資源最後的更改時間進行比較,看資源是否發生了更改。如果沒有發生更改,則會返回狀態碼為304的響應,如果發生了更改就會返回狀態碼為200的響應。
- Etag/If-None-Match
Etag是由伺服器端生成的一段hash code.預設的計算方式是“檔案的最後修改時間16進位制-檔案長度16進位制”。伺服器端在響應客戶請求的時候會帶上Etag,之後客戶端請求就會通過If-None-Match攜帶上Etag。然後客戶端會根據是否命中來決定返回304還是200.
專案實踐
上面說了這麼多概念性的東西,下面我來說一下我自己專案中一些快取的實踐吧。我們在專案開發中關於快取會有以下幾點的設定:
-
1.將JS,CSS,圖片等靜態資源的有效時間設定得很大(max-age=31536000),儘量命中強快取。
-
2.將html的資源的有效時間設定得很短(max-age=0,或者cahe-control:no-store/no-cache).這樣可以避免html不更新讀取不到最新得資原始檔。
-
3.在使用webpack打包時,將js,css,圖片等靜態資源使用contentHash來命名打包出來的檔案。
entry:{
main: path.join(__dirname,'./main.js'),
vendor: ['react', 'antd']
},
output:{
path:path.join(__dirname,'./dist'),
publicPath: '/dist/',
filname: 'bundle.[contentHash].js'
}
複製程式碼
- 4.最後部署時採用非覆蓋式的部署。
最後
以上如果有說得不對的地方,歡迎指正~~