一、瀏覽器緩存簡介
- 1、瀏覽器通過緩存服務器返回的資源(針對靜態資源和get請求),減少傳輸壓力,提高訪問速度。
- 2、那麼緩存的目標應該是:資源可以被緩存 + 保證不使用過期的資源 + 服務器資源部分更新的時候不能導致新舊文件內容不一致。所以可以結合實際情況,設置適當的緩存策略。
- 3、瀏覽器無緩存的過程:
瀏覽器請求 ---> 無緩存 ---> 請求WEB服務器 ---> 請求響應 ---> 呈現 -
4、瀏覽器有緩存的過程:
瀏覽器請求 ---> 有緩存 ---> 校驗過期(無需發請求) ---> 是否有更新(需要發請求,結合Etag或Last-Modified驗證更新) ---> 呈現二、常見緩存策略
http本身是個協議,緩存是瀏覽器實現的。可以通過設置或讀取HTTP頭來實現對應的緩存機制(強緩存和協商緩存)。
-
1、 強緩存策略(可以強制緩存並定義足夠長的過期時間讓資源在本地長期駐留,但是不能及時更新):Cache-Control和Expire
- Cache-Control:max-age 的優先級要比Expires高。若命中,則不向服務器發請求。
- Expires有弊端:是絕對時間,依賴客户端時間,可能和服務端時間不一致。
-
2、協商緩存(用於檢測新鮮度,協商緩存能夠保證及時更新,但是會頻繁地去服務器驗證,浪費性能):Etag(和If-None-Match一對) 和 Last-Modified(和If-Modified-Since一對);每次都要向服務器get請求驗證。
-
Last-Modified有缺陷:
- (1)只是編輯了文件,但是文件內容沒有變化,Last-Modified也會改變
- (2)Last-Modified只能精確到s,如果文件操作在ms級操作,則精確不到
-
Etag根據文件內容生成hash(通常最終的 ETag 將由實體的長度和哈希值兩部分組成。),更精確,也有缺陷:
- (1)服務器計算etag需要額外的性能開銷
- (2)分強驗證(每個字節都相同)和弱驗證(部分字節相同),要根據具體的業務場景合理選擇。
-
-
3、緩存優先級:
-
Cache-Control(強) > Expires (強)> Etag / If-None-Match > Last-Modified / If-Modified-Since
三、實踐
-
-
index.html入口資源:
- 要保證及時更新,可設置協商緩存,cache-control: no-cache
-
cdn上的資源
- 如vue,不經常變動,路徑中有版本號,可以設置很長的時間,如cache-control: max-age=31536000(一年)
- cdn上的配置文件,有可能會很快變化,有可能也不快,可設置cache-control: max-age=86400(一天)(可用cdn的主動刷新機制)
-
圖片,視頻等資源
- 不經常更改且佔用緩存空間大,可設置強緩存且過期時間不宜太長,如cache-control: max-age=86400(一天)
-
項目的業務CSS和JS等資源
- 內容可能不定期修改,可結合webpack生成帶hash的文件,如style.51af3464.css。如果文件內容變了,打包後的hash也會變,url就會變,瀏覽器會重新請求,所以過期時間可以很長。如cache-control: max-age=31536000(一年)
-
JS腳本文件:如果js資源中包含私人信息,則不能讓中間代理緩存,則要為cache-control添加private
四、示例
1、無緩存no-cache
五、用户行為對瀏覽器緩存的影響
所謂用户行為對瀏覽器緩存的影響,指的就是用户在瀏覽器如何操作時,會觸發怎樣的緩存策略。主要有 3 種:
- 打開網頁,地址欄輸入地址: 查找 disk cache 中是否有匹配。如有則使用;如沒有則發送網絡請求。
- 普通刷新 (F5):因為 TAB 並沒有關閉,因此 memory cache 是可用的,會被優先使用(如果匹配的話)。其次才是 disk cache。
- 強制刷新 (Ctrl + F5):瀏覽器不使用緩存,因此發送的請求頭部均帶有 Cache-control: no-cache(為了兼容,還帶了 Pragma: no-cache),服務器直接返回 200 和最新內容。