廢話不多說,先上一張結構圖:
前端所涉及到的快取技術主要就是圖中所示,是不是很清晰很簡單?其中,關於本地儲存(LocalStorage、SessionStorage)是在具體的業務邏輯中使用的。本文主要介紹前端工程體系下的快取配置策略(也就是瀏覽器對於JS、css、圖片等靜態資源的快取策略)
HTTP快取策略
瀏覽器對靜態資源的快取本質上是HTTP協議的快取策略,根據是否要向服務端傳送請求的不同,HTTP快取策略又可分為強制快取和協商快取策略。
1、強制快取策略
瀏覽器不發請求,根據過期時間決定使用本地快取還是請求新資源,這樣的策略就叫做強制快取策略。
Expires和Cache-control是強制快取策略的重要響應頭資訊。
(1)Expires
Expires是HTTP1.0加入的特性,通過指定一個明確的時間點作為快取資源的過期時間,也就是說在這個時間點之前如果再次請求此資源的話,瀏覽器會直接去快取裡面取,不會再發出請求。例如:(來自掘金網站analytics.js的請求)
expires: Wed, 19 Sep 2018 10:36:19 GMT
複製程式碼
但是Expires有個很嚴重的問題:它是以伺服器時間來定的,但是瀏覽器進行過期判斷是將本地的時間與它作對比,這樣就會存在誤差(例如伺服器在中國,你在美國用瀏覽器訪問),這顯然是不合理的。
(2)Cache-control
為了解決Expires的問題,HTTP1.1新增了一個響應頭資訊:Cache-control。常用的Cache-control有以下幾種:
no-cache:指定瀏覽器向服務端發出請求,經服務端確認資源是否發生變化,如果未發生變化就可以使用瀏覽器快取(即協商快取策略),如果發生變化則重新下載新資源。
no-store:指定瀏覽器向服務端發出請求,無論資源是否發生變化,都會重新下載資源。是真正意義上的禁止快取。
max-age:指定從請求的時刻算起,此資源能夠被快取的最長時間,單位是秒。例如analytics.js的請求max-age=7200
,表示瀏覽器在2小時內如果再次遇到對於此資源的請求,會使用本地的快取。
max-age指定的是一個時間段,相當於是絕對值,所以不受瀏覽器和伺服器之間時間的影響。它比Expires具有更高的優先順序。
2、協商快取策略
瀏覽器會發出新請求,經過伺服器對資源的對比後決定採用本地快取還是新資源,這樣的策略叫做協商快取策略。(顧名思義,就是瀏覽器和伺服器協商來解決這件事)
判斷啟用協商快取策略的標準是:Cache-control設定為no-cache或者max-age與Expires都過期的情況下。
Etag和If-none-match
Etag是伺服器為資源分配的唯一性標識,作為響應頭資訊返回給瀏覽器。當採用協商快取策略時,瀏覽器會將Etag值通過If-none-match作為請求頭髮送給伺服器,伺服器收到請求後,會對比所請求資源的Etag值是否改變,如果未改變將會返回304 Not Modified,告訴瀏覽器這個檔案沒有任何變化,那麼瀏覽器就回去快取中取;如果資源發生了改變,伺服器就會返回最新的資源並且重置資源的Etag值。
最後獻上一張前端快取策略流程圖:(畫了挺久的,畫完也比較滿意啊哈哈哈~!)
PS:當瀏覽器取本地快取的時候,在Network裡面size一欄我們可能會看到2種描述:from memory cache和from disk cache。
from memory cache:從記憶體中取,關閉瀏覽器就沒了。一般指令碼檔案、字型、圖片會存在記憶體當中。
from disk cache:從磁碟中取,關閉瀏覽器再開啟該請求依然還能在磁碟中取。一般非指令碼檔案會存在記憶體當中,如css等