博客 / 詳情

返回

網站 cache control 最佳實踐

推薦閲讀:

  • 2020年軟件開發趨勢
  • 高併發案例 - 庫存超發問題
  • 負載均衡的分類及算法
  • 異地多活架構
  • Postman 的替代品來了

有時,當第二次訪問網站時,看起來比較怪,樣式不正常。

通常,是因為 cache control 緩存控制策略定義不正確,導致服務端最新部署之後客户端沒有接收到最新的更改。

本文將向您展示正確的緩存設置,以便在每次部署後使所有用户的網站保持最新狀態。

緩存在後台如何工作?

瀏覽器為了提高性能,向服務器請求資源時,都儘量多從本地緩存獲取,儘量少從服務器獲取。

具體行為我們可以通過指令來控制,通過設置 HTTP 響應頭來實現。

緩存處理相關的最常用指令包括:

  • Cache-Control
  • Expires
  • Etag
  • Last-Modified

如果沒有設置緩存控制指令,瀏覽器將從服務器獲取每個資源,這會增加頁面的加載時間。

沒有緩存設置的請求流程:

由瀏覽器決定如何在沒有服務器指示的情況下緩存信息。

不同瀏覽器策略不同,例如 Chrome 和 Safari 每次都從後端下載數據。

為了清楚地定義緩存的處理方式,讓我們深入瞭解一下緩存控制指令。

Etag(實體標籤)

Etag 可以讓我們在不用下載資源的情況下,就知道服務器上的資源是否變更了。

服務器在給瀏覽器發送資源文件時(例如 css 文件),會對此資源內容計算出一個 hash 值,作為此文件的 tag,一起發送給瀏覽器。

瀏覽器下次請求此資源文件時,先把這個 tag 發給服務器,HTTP header 信息例如:

If-None-Match: W/“1d2e7–1648e509289”

服務器和本地文件的 hash 值對比。

如果一樣,就告訴瀏覽器沒有變化,可以使用緩存文件,否則瀏覽器下載新文件。

使用Etag請求流-第一次加載:

使用Etag請求流-第二次加載:

啓用 Etag 緩存策略後,我們總是會去服務器檢查文件的哈希值,然後瀏覽器才會決定從緩存中提取文件或將其完全加載。

如果未修改,則無論您要請求的是10KB還是10MB的文件,只需80–100字節即可進行驗證。

Last Modified

服務器有每個文件的最後修改時間戳,在第一次文件加載之後,客户端會向服務器詢問此文件在某時間之後是否更改過。

HTTP header 信息例如:

If-Modified-Since: Fri, 13 Jul 2018 10:49:23 GMT

如果改了,就下載新文件,否則使用緩存。

看着挺好,但現實情況並不一定是這樣的,“Last-Modified” 是一個弱緩存頭信息,瀏覽器有自己的緩存策略,會自行決定是否從緩存中獲取資源或下載新文件,不同瀏覽器處理方式也不一樣。

使用 Last-Modified 的請求流程 - 第一次加載:

使用 Last-Modified 的請求流程 - 第二次加載(完美情況):

使用 Last-Modified 的請求流程 - 第二次加載(通常情況):

所以,“Last-Modified” 是不可靠的,我寧願完全不使用他。

Cache-Control max-age

這個指令告訴瀏覽器此文件在本地緩存多長時間。

以秒為單位,形式為:

Cache-Control: max-age=31536000

使用此策略後,瀏覽器完全不用向服務器發起請求了,直接使用本地緩存,非常快。

但是,沒有辦法確保這段時間內服務器中的文件不會修改。

因此,為了讓瀏覽器下載最新的文件,我們可以使用一些構建工具,例如 Webpack、Gulp。

每個文件都在服務器中進行預編譯,對文件內容進行 hash 計算,把 hash 值添加到文件名中,例如 “app-72420c47cc.css”。

這樣,文件內容的變化就可以反應在文件名上,對瀏覽器來講就是一個新的文件,舊文件的緩存也就沒有了,會從服務器上獲取新的。

這個方法適用於 CSS JS 和圖片文件。

no-cache

no-cache(無緩存)不意味着根本沒有緩存,它只是告訴瀏覽器在使用緩存之前先驗證服務器上的資源。

需要與 Etag 一起使用,因此瀏覽器將發送一個簡單請求並加載額外的80個字節以驗證文件的狀態。

對於 HTML 文件,就需要使用 “no-cache”。

最終方案

使用 Gulp,Webpack 這類工具將唯一的哈希值添加到 css,js 和圖像文件(如app-67ce7f3483.css)。

對於 js,css 和圖像文件,設置 Cache-Control:public,max-age = 31536000,不設置 Etag 和 Last-Modified。

對於 HTML 文件,設置 Cache-Control: no-cache 和 Etag。

翻譯整理自:

https://medium.com/pixelpoint...

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.