本文主要介紹在沒有設置強制緩存時的 lm factor 算法,以及關於緩存策略的思考。以及如何使用 service worker 加強緩存。前端
本文地址 shanyue.tech/post/a-prob…web
前幾天,寫了一篇博客,瀏覽器中的二進制,其中總結了一張圖。面試
後來,我對圖片作了一些更改,又發佈了上去。這時候問題出現了,圖片沒有更新!算法
比沒有緩存更嚴重的問題是緩存了不應緩存的東西!docker
我研究了下該圖片的 Request/Response 信息,總結以下瀏覽器
如今再來看文章開頭那張圖,若是這是一段面試題,第二次請求圖片資源應該是哪一種緩存策略緩存
再拋出一個問題,如何得出某資源的最後更新時間以及本次請求資源所生成的時間服務器
先熟悉如下兩個 Response Header網絡
從這兩個頭能夠計算出資源已經多久沒有更新了。frontend
LM factor 算法在沒有 Cache-Control 以及 Expires 的時候,用來計算應該強制緩存多長時間。
算法大體介紹以下,若是本次請求資源,發現沒有關於強制緩存的配置,並且該資源最後一次修改是在 10 小時之前,那麼就對它設置 10 * factor 個小時的緩存。factor 即 LM factor,設置爲 (0, 1)。
若是你不設置 Cache-Control 的話,那你的資源很危險,用戶可能正在訪問已過時的資源!
另外,在對你的應用進行二次刷新時,你大部分資源都進了緩存,加載速度很快。先不要高興太早,有可能不是你緩存設置得好,更有多是你壓根就沒設置緩存。
一言蔽之,不管如何,要主動設置 Cache-Control,不要讓瀏覽器替你作決策
找到了問題所在,只需添加一個響應頭 Cache-Control: no-cache;
就能夠解決問題。
no-cache 表明須要每次校驗資源的新鮮度,來決定是否從緩存中取 no-store 表明從不存緩存
因爲博客沒有能作長期緩存的資源,統一對博客的全部請求添加了響應頭 Cache-Control: no-cache
。我使用了 Traefik
做爲反向代理,修改 docker-compose.yml 以下
version: "3"
services:
blog:
build:
context: .
restart: always
labels:
- "traefik.frontend.rule=Host:blog.xiange.tech"
- "traefik.frontend.headers.customResponseHeaders=Cache-Control:no-cache"
複製代碼
再次部署後,圖片緩存的問題已經解決。
這時再思考一個項目的緩存策略設置
圖片總結以下,參考谷歌開發者文檔 developers.google.com/web/fundame…
而個人緩存策略簡單總結以下
若是 304 過多怎麼辦
若是不帶指紋的資源過多,又須要資源保障實時的新鮮度如何處理。這麼一大堆資源每次去向服務器比對 ETag,服務器也是很煩的,畢竟也會消耗一些 CPU。
這時候能夠考慮使用 service worker 作緩存加強。
此時,只須要 sw.js 每次校驗新鮮度,而無需一大堆文件都去校驗新鮮度了