推薦閱讀:css
有時,當第二次訪問網站時,看起來比較怪,樣式不正常。web
一般,是由於 cache control 緩存控制策略定義不正確,致使服務端最新部署以後客戶端沒有接收到最新的更改。算法
本文將向您展現正確的緩存設置,以便在每次部署後使全部用戶的網站保持最新狀態。後端
瀏覽器爲了提升性能,向服務器請求資源時,都儘可能多從本地緩存獲取,儘可能少從服務器獲取。瀏覽器
具體行爲咱們能夠經過指令來控制,經過設置 HTTP 響應頭來實現。緩存
緩存處理相關的最經常使用指令包括:服務器
若是沒有設置緩存控制指令,瀏覽器將從服務器獲取每一個資源,這會增長頁面的加載時間。架構
沒有緩存設置的請求流程:併發
由瀏覽器決定如何在沒有服務器指示的狀況下緩存信息。app
不一樣瀏覽器策略不一樣,例如 Chrome 和 Safari 每次都從後端下載數據。
爲了清楚地定義緩存的處理方式,讓咱們深刻了解一下緩存控制指令。
Etag 可讓咱們在不用下載資源的狀況下,就知道服務器上的資源是否變動了。
服務器在給瀏覽器發送資源文件時(例如 css 文件),會對此資源內容計算出一個 hash 值,做爲此文件的 tag,一塊兒發送給瀏覽器。
瀏覽器下次請求此資源文件時,先把這個 tag 發給服務器,HTTP header 信息例如:
If-None-Match: W/「1d2e7–1648e509289」
服務器和本地文件的 hash 值對比。
若是同樣,就告訴瀏覽器沒有變化,可使用緩存文件,不然瀏覽器下載新文件。
使用Etag請求流-第一次加載:
使用Etag請求流-第二次加載:
啓用 Etag 緩存策略後,咱們老是會去服務器檢查文件的哈希值,而後瀏覽器纔會決定從緩存中提取文件或將其徹底加載。
若是未修改,則不管您要請求的是10KB仍是10MB的文件,只需80–100字節便可進行驗證。
服務器有每一個文件的最後修改時間戳,在第一次文件加載以後,客戶端會向服務器詢問此文件在某時間以後是否更改過。
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=31536000
使用此策略後,瀏覽器徹底不用向服務器發起請求了,直接使用本地緩存,很是快。
可是,沒有辦法確保這段時間內服務器中的文件不會修改。
所以,爲了讓瀏覽器下載最新的文件,咱們可使用一些構建工具,例如 Webpack、Gulp。
每一個文件都在服務器中進行預編譯,對文件內容進行 hash 計算,把 hash 值添加到文件名中,例如 「app-72420c47cc.css」。
這樣,文件內容的變化就能夠反應在文件名上,對瀏覽器來說就是一個新的文件,舊文件的緩存也就沒有了,會從服務器上獲取新的。
這個方法適用於 CSS JS 和圖片文件。
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...