理解瀏覽器緩存

瀏覽器緩存機制

  • HTTP 緩存分爲 2 種,一種是強緩存,另一種是協商緩存。
  • 主要作用是可以加快資源獲取速度,提升用戶體驗,減少網絡傳輸,緩解服務端的壓力。這是緩存運作的一個整體流程圖:

在這裏插入圖片描述

緩存位置

從緩存位置上來說分爲四種,並且各自有優先級,當依次查找緩存且都沒有命中的時候,纔會去請求網絡。

Service Worker
Memory Cache
Disk Cache
Push Cache

強緩存

  • 不需要發送請求到服務端,直接讀取瀏覽器本地緩存
  • 在 Chrome 的 Network 中顯示的 HTTP 狀態碼是 200
  • 在 Chrome 中,強緩存又分爲 Disk Cache (存放在硬盤中)和 Memory Cache (存放在內存中)
  • 存放的位置是由瀏覽器控制的。
  • 是否強緩存由 Expires、Cache-Control 和 Pragma 3 個 Header 屬性共同來控制。
Expires
  • Expires 的值是一個 HTTP 日期,在瀏覽器發起請求時,會根據系統時間和 Expires 的值進行比較,
  • 如果系統時間超過了 Expires 的值,緩存失效。由於和系統時間進行比較,所以當系統時間和服務器時間不一致的時候,會有緩存有效期不準的問題。
  • Expires 的優先級在三個 Header 屬性中是最低的。
Cache-Control
  • Cache-Control 是 HTTP/1.1 中新增的屬性,在請求頭和響應頭中都可以使用,常用的屬性值如有:
  • max-age:單位是秒,緩存時間計算的方式是: 從發起請求的時間秒數開始算起,當用戶再次發起請求,如果這個時間大於max-age設置的時間間隔,緩存失效。
  • no-cache:不使用強緩存,需要與服務器驗證緩存是否新鮮
  • no-store:禁止使用緩存(包括協商緩存),每次都向服務器請求最新的資源
  • private:專用於個人的緩存,中間代理、CDN 等不能緩存此響應
  • public:響應可以被中間代理、CDN 等緩存
  • must-revalidate:在緩存過期前可以使用,過期後必須向服務器驗證
Pragma
  • Pragma 只有一個屬性值,就是 no-cache ,效果和 Cache-Control 中的 no-cache 一致,不使用強緩存,需要與服務器驗證緩存是否新鮮,在 3 個頭部屬性中的優先級最高。

協商緩存

  • 當瀏覽器的強緩存失效的時候或者請求頭中設置了不走強緩存,並且在請求頭中設置了If-Modified-Since 或者 If-None-Match 的時候,會將這兩個屬性值到服務端去驗證是否命中協商緩存,如果命中了協商緩存,會返回 304 狀態,加載瀏覽器緩存,並且響應頭會設置 Last-Modified 或者 ETag 屬性。

  • ETag/If-None-Match
    ETag/If-None-Match 的值是一串 hash 碼,代表的是一個資源的標識符,當服務端的文件變化的時候,它的 hash碼會隨之改變,通過請求頭中的 If-None-Match 和當前文件的 hash 值進行比較,如果相等則表示命中協商緩存。ETag 又有強弱校驗之分,如果 hash 碼是以 “W/” 開頭的一串字符串,說明此時協商緩存的校驗是弱校驗的,只有服務器上的文件差異(根據 ETag 計算方式來決定)達到能夠觸發 hash 值後綴變化的時候,纔會真正地請求資源,否則返回 304 並加載瀏覽器緩存。(意思就是說可能服務器文件變化了,但是沒有觸發hash值的改變)

  • Last-Modified/If-Modified-Since
    Last-Modified/If-Modified-Since 的值代表的是文件的最後修改時間,第一次請求服務端會把資源的最後修改時間放到 Last-Modified 響應頭中,第二次發起請求的時候,請求頭會帶上上一次響應頭中的 Last-Modified 的時間,並放到 If-Modified-Since 請求頭屬性中,服務端根據文件最後一次修改時間和 If-Modified-Since 的值進行比較,如果相等,返回 304 ,並加載瀏覽器緩存。

那麼協商緩存爲什麼又分爲兩種?後者解決了前者的什麼問題?

ETag/If-None-Match 的出現主要解決了 Last-Modified/If-Modified-Since 所解決不了的問題:

一、如果文件的修改頻率在秒級以下(可能文件添加一個空格又刪除了),Last-Modified/If-Modified-Since 會錯誤地返回
二、如果文件被修改了,但是內容沒有任何變化的時候,Last-Modified/If-Modified-Since 會錯誤地返回。

優先級排序
  • 強緩存
  • 進行協商緩存時,應該是有Etag就檢查Etag,沒有的話就檢查 Last-Modified。兩者是二選一的關係,Etag 優先級更高。

用戶行爲對瀏覽器緩存的影響

所謂用戶行爲對瀏覽器緩存的影響,指的就是用戶在瀏覽器如何操作時,會觸發怎樣的緩存策略。主要有 3 種:

一、打開網頁,地址欄輸入地址: 查找 disk cache 中是否有匹配。如有則使用;如沒有則發送網絡請求。
二、普通刷新 (F5):因爲 Tab頁 並沒有關閉(會話沒有斷開),因此 memory cache 是可用的,會被優先使用(如果匹配的話)。其次纔是 disk cache。
三、強制刷新 (Ctrl + F5):瀏覽器不使用緩存,因此發送的請求頭部均帶有 Cache-control: no-cache(爲了兼容,還帶了 Pragma: no-cache),服務器直接返回 200 和最新內容。

實際開發衆遇到的緩存不更新問題

一、一個業務代碼開發完畢,重新打包上線。
二、如果前端打包後的文件名沒有設置內容hash值(保證前端代碼內容更改,打包出來的bundle.js名字更改),
三、並且不重啓服務器,此時就會出現緩存不更新的問題。
(判斷強緩存新鮮不新鮮,暫時理解爲 服務器中的資源文件名字有沒有變化)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章