瀏覽器緩存:memory cache、disk cache、強緩存協商緩存等概念

分類

從緩存位置上來說分爲四種:

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

如果以上四種緩存都沒有命中的話,那麼只能發起請求來獲取資源了。

memory cache

Memory Cache 也就是內存中的緩存

優點:
讀取速度快

缺點:
一旦我們關閉 Tab 頁面,內存中的緩存也就被釋放了。

如何觸發:
當我們訪問過頁面以後,再次刷新頁面,可以發現很多數據都來自於內存緩存
在這裏插入圖片描述

disk cache

Disk Cache 也就是存儲在硬盤中的緩存

優點:
緩存再硬盤中,容量大

缺點:
讀取速度滿

如何觸發:
根據瀏覽器請求頭

瀏覽器會把哪些文件丟進內存中?哪些丟進硬盤中?
關於這點,網上說法不一,不過以下觀點比較靠得住:
對於大文件來說,大概率是不存儲在內存中的,反之優先
當前系統內存使用率高的話,文件優先存儲進硬盤

Service Worker

  • Service Worker 是運行在瀏覽器背後的獨立線程,一般可以用來實現緩存功能。
  • 傳輸協議必須爲 HTTPS
  • Service Worker 的緩存與瀏覽器其他內建的緩存機制不同,它可以讓我們自由控制緩存哪些文件、如何匹配緩存、如何讀取緩存,並且緩存是持續性的。

這個我們不常用

Push Cache

  • Push Cache(推送緩存)是 HTTP/2 中的內容,當以上三種緩存都沒有命中時,它纔會被使用。
  • 它只在會話(Session)中存在,一旦會話結束就被釋放,並且緩存時間也很短暫

這個我們不常用

緩存過程

在這裏插入圖片描述
根據是否需要向服務器重新發起HTTP請求將緩存過程分爲兩個部分,分別是強緩存和協商緩存。

強緩存

不會向服務器發送請求,直接從緩存中讀取資源。

在chrome控制檯的Network選項中可以看到該請求返回200的狀態碼,並且Size顯示from disk cache或from memory cache。

強緩存可以通過設置兩種 HTTP Header 實現:Expires 和 Cache-Control。

1、Expires

緩存過期時間,用來指定資源到期的時間,是服務器端的具體的時間點。

2、Cache-Control

比如:Cache-Control:max-age=300 時,則代表在這個請求正確返回的5分鐘內再次加載資源,就會命中強緩存。
在這裏插入圖片描述

Expires 和 Cache-Control 的差別

其實這兩者差別不大,區別就在於 Expires 是http1.0的產物,Cache-Control是http1.1的產物,兩者同時存在的話,Cache-Control優先級高於Expires;在某些不支持HTTP1.1的環境下,Expires就會發揮用處。所以Expires其實是過時的產物,現階段它的存在只是一種兼容性的寫法。

強緩存判斷是否緩存的依據來自於是否超出某個時間或者某個時間段,而不關心服務器端文件是否已經更新,這可能會導致加載文件不是服務器端最新的內容,那我們如何獲知服務器端內容是否已經發生了更新呢?此時我們需要用到協商緩存策略。

協商緩存

協商緩存就是強制緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程,主要有以下兩種情況:

  1. 協商緩存生效,返回304和Not Modified
    在這裏插入圖片描述
  2. 協商緩存失效,返回200和請求結果
    在這裏插入圖片描述
    協商緩存可以通過設置兩種 HTTP Header 實現:Last-Modified 和 ETag 。

Last-Modified和If-Modified-Since

Last-Modified 指的是這個資源在服務器上的最後修改時間

瀏覽器下一次請求這個資源,瀏覽器檢測到有 Last-Modified這個header,於是添加If-Modified-Since這個header,值就是Last-Modified中的值;服務器再次收到這個資源請求,會根據 If-Modified-Since 中的值與服務器中這個資源的最後修改時間對比,如果沒有變化,返回304和空的響應體,直接從緩存讀取,如果If-Modified-Since的時間小於服務器中這個資源的最後修改時間,說明文件有更新,於是返回新的資源文件和200
在這裏插入圖片描述

弊端:

  • 如果本地打開緩存文件,即使沒有對文件進行修改,但還是會造成 Last-Modified 被修改,服務端不能命中緩存導致發送相同的資源
  • 因爲 Last-Modified 只能以秒計時,如果在不可感知的時間內修改完成文件,那麼服務端會認爲資源還是命中了,不會返回正確的資源

既然根據文件修改時間來決定是否緩存尚有不足,能否可以直接根據文件內容是否修改來決定緩存策略?所以在 HTTP / 1.1 出現了 ETag 和If-None-Match

ETag和If-None-Match

Etag是服務器響應請求時,返回當前資源文件的一個唯一標識(由服務器生成),只要資源有變化,Etag就會重新生成。
在這裏插入圖片描述

協商緩存的兩者對比

精度:Etag 要優於 Last-Modified。
性能:Last-Modified 要優於 Etag。
優先級:服務器校驗優先考慮Etag

實際使用策略

對與頻繁變動的資源:
使用 Cache-Control: no-cache,使瀏覽器每次都請求服務器,然後配合 ETag 或者 Last-Modified 來驗證資源是否有效。這樣的做法雖然不能節省請求數量,但是能顯著減少響應數據大小。

對於不常變化的資源:
通常在處理這類資源時,給它們的 Cache-Control 配置一個很大的 max-age=31536000 (一年),這樣瀏覽器之後請求相同的 URL 會命中強制緩存。而爲了解決更新的問題,就需要在文件名(或者路徑)中添加 hash, 版本號等動態字符,之後更改動態字符,從而達到更改引用 URL 的目的,讓之前的強制緩存失效 (其實並未立即失效,只是不再使用了而已)。

用戶行爲如何觸發緩存

  • 打開網頁,地址欄輸入地址: 查找 disk cache 中是否有匹配。如有則使用;如沒有則發送網絡請求。
  • 普通刷新 (F5):因爲 TAB 並沒有關閉,因此 memory cache 是可用的,會被優先使用(如果匹配的話)。其次纔是 disk cache。
  • 強制刷新 (Ctrl + F5):瀏覽器不使用緩存,因此發送的請求頭部均帶有 Cache-control: no-cache(爲了兼容,還帶了 Pragma: no-cache),服務器直接返回 200 和最新內容。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章