各种浏览器缓存浅析
前言
目前瀏覽器的緩存類型眾多,HTTP Cache、Disk Cache、Memory Cache、ServiceWorker Cache、Push Cache 等等,這些緩存是如何產生的?命中優先級是怎么樣?又該如何去使用它們?
Disk Cache、Memory Cache
Disk Cache、Memory Cache 屬于強緩存,將緩存的響應寫到內存或硬盤中,也屬于 HTTP 緩存的產物。
強緩存是如何產生的?
強緩存的產生依賴于請求響應中的 cache-control 和 expires 的 headers 字段。這兩個字段都是用來設置緩存數據的有效時間。
- expires 是 HTTP 1.0 的產物,表示的是緩存的到期時間,是一個絕對時間。
- cache-control 是 HTTP 1.1 的產物,表示的是緩存的最大可用時長,是一個相對時間。
cache-control 字段的值,也需要搭配相應的字段來使用,常用字段:
- max-age:緩存的時長,和 expires 的作用類似,單位是秒。
- no-cache:忽略強緩存,真接走協商緩存。
- no-store:忽略強緩存和協商緩存,直接從服務器獲取響應。
- public:所有的數據都可以被任意地方緩存(例如可以緩存到 CDN 和代理服務器上)。
- private:默認值,所有內容只有客戶端才可以緩存。
兩個字段同時存在時,cache-control 優先級最高。
內存緩存和硬盤緩存如何存儲的?
當請求響應符合強緩存時,瀏覽器會根據 header 頭中的字段類型進行緩存處理。通常:
- 內存緩存:會存放 腳本、base64數據和字體等。
- 硬盤緩存:會存放 樣式文件、圖片或比較大的文件等。
此行為屬于瀏覽器行為,服務器不可控。
區別
| Disk Cache | - 長期存在:瀏覽器關閉時同樣存在。 - 存儲文件空間更大。 |
| Memory Cache | - 短期存在:生命周期為會話級的,回話結束 緩存清除。 - 訪問速度更快。 - 優先級更高。 |
HTTP Cache
這里主要說的是返回狀態碼為 304 的這種協商緩存。
當強緩存失效后,瀏覽器就會攜帶緩存標志向服務器發送請求。這里主要用到的 header 頭:
- Etag / If-None-Match
- Last-Modified / If-Modified-Since:
當收到請求的響應時,會攜帶:
- Etag:是服務器基于某種規則對資源生成的一個標志,類似于文件 hash。
- Last-Modified:是服務器返回文件最后修改的時間。
當發送請求的時候,瀏覽器會攜帶:
- If-None-Match:對應的就是 Etag 的值。
- If-Modified-Since:對應的就是 Last-Modified 的值。
服務器根據這兩個值進行匹配,如果相等,說明文件沒有變化,返回 304,瀏覽器直接從緩存里面取;當不相等時,服務器發送最新的內容,狀態碼為 200。
ServiceWorker Cache
ServiceWorker Cache 屬于新的 PWA Cache Storage API,它有力度更細的程序可操作緩存的能力。
它的命中條件依賴于 fetch,所以它的命中順序如下:
是否從 serviceworker Cache 里面取緩存,完全依賴于 serviceworker 的腳本控制,取決于用戶自定義。
瀏覽器上對應操作
| 刷新按鈕 或 cmd + r | 有效 | 有效 | 有效 | 無變動 |
| cmd + shift + r | 無效 | 無效 | 無效 | 請求中無 If-None-Match/If-Modified-Since,Cache-Control 值為 no-cache。 |
| DevTools Network面板開啟Disable cache | 無效 | 無效 | 無效 | 同上,但無緩存的能力更強 |
總結
- 上一篇: 带研发团队后的日常思考1 初级管理者的困
- 下一篇: Hbase Java API详解