緩存專題:HTML5離線緩存與HTTP緩存

寫在前面

原本是筆記,沒想到寫着寫着就有了點文章的意思,那乾脆就完善一下發上來吼!這裏總結了幾乎全部與緩存有關的內容,包括HTTP緩存中的全部頭部和相應用法說明,以及對應的分組,幫助你們記憶,還有離線緩存中須要注意的點。javascript

喜歡請點贊,有問題歡迎留言討論,若有紕漏還請指正。😄css

HTML5離線緩存

manifest

HTML5離線緩存主要經過html元素的manifest屬性指定一個後綴爲manifest的文件,該文件爲網頁指定哪些文件須要被緩存,哪些不須要緩存,以及獲取失敗的處理方式等等,該文件主要包含四個部分:html

  1. CACHE MANIFEST:標題,位於文件首行,若是沒有指定標題,會致使文件解析失敗java

  2. CACHE:該部分指定須要緩存的文件列表,內容爲相對路徑,對應html文件中引入的路徑,通常來講主文檔無需添加,默認緩存。ajax

  3. NETWORK:指定不須要緩存的文件,即永遠從服務端獲取。算法

  4. FALLBACK:指定文件獲取失敗後的處理方式。如:chrome

CACHE MANIFEST

CACHE:
./js/main.js
./css/main.css

NETWORK:
signup.html # 不緩存登錄頁面

FALLBACK:
signup.html offline.html
# 當沒法獲取到該路徑下的請求時,全部請求都會被轉發到default.html文件來處理
/app/ajax/ default.html
複製代碼

其工做流程大體以下:瀏覽器

  1. 首次訪問頁面,瀏覽器加載頁面和所需資源
  2. 解析到html元素的manifest文件,加載CACHE以及FALLBACK對應的資源到緩存中
  3. 從如今起你將徹底使用瀏覽器緩存中的文件,即便強制刷新也不會生效。隨後瀏覽器會嘗試檢查manifest文件是否更新(聯機狀態纔會檢查)。若manifest文件更新,瀏覽器會下載全部資源並更新緩存。
  4. 離線狀態下訪問已緩存的資源時,瀏覽器會從緩存中讀取,而相應的,訪NETWORK中的資源則會對應讀取FALLBACK

注意點:只有manifest文件更新,瀏覽器纔會從新下載新資源,意味着僅僅更改資源文件內容是不會觸發更新的。這一問題能夠經過在manifest中添加版本註釋來解決。且更新緩存並不會當即生效,需下次訪問生效!可經過瀏覽器API監聽相應的事件,提醒用戶刷新瀏覽器。緩存

applicationCache API

這是一個操做緩存的瀏覽器接口,window.applicationCache對象能夠觸發一系列與緩存狀態相關的事件,其status屬性0~5也對應了不一樣的狀態,這裏不展開了就:bash

window.applicationCache.oncached = function (e) {
  console.log('cached!')
}
window.applicationCache.onchecking = function (e) {
  console.log('checking!')
}
window.applicationCache.ondownloading = function (e) {
  console.log('downloading!')
}
window.applicationCache.onerror = function (e) {
  console.log('error!', e)
}
window.applicationCache.onnoupdate = function (e) {
  console.log('noupdate!')
}
window.applicationCache.onupdateready = function (e) {
  console.log('updateready!')
}
複製代碼

另外可經過在瀏覽器地址欄輸入:chrome://appcache-internals(因瀏覽器而異)

緩存內容

能夠選擇查看細節或刪除緩存

HTTP緩存

強緩存

Cache-Control(HTTP/1.1)

通用字段

  • no-cache:本地能夠緩存,可是每次使用都要向服務器驗證,不管是否過時
  • no-store:徹底不能夠緩存,每次都要去服務器拿最新的值
  • max-age:客戶端瀏覽器緩存時間
  • no-transform: 禁止代理改動返回的內容,如禁止代理服務器壓縮圖片

請求字段

  • max-stale:(寬容)代理緩存過時沒關係,只要在時間限制內就行
  • min-fresh:(限制)代理緩存須要必定新鮮度,要提早拿,不然拿不到
  • only-if-cached:客戶端只接受代理服務器的緩存,不會去源服務器拿,代理過時則直接返回504(Gateway Timeout)

響應字段

  • public:全部中間層均可以緩存(客戶端,代理)
  • private:只有客戶端能夠緩存
  • s-maxage:代理服務器緩存時間(會覆蓋max-age,expires)
  • must-revalidate:緩存過時以前能夠直接使用,一旦過時必須向服務器驗證。會忽略max-stale頭部
  • proxy-revalidate:中間服務器接收到客戶端帶有這個頭部的請求時,在返回數據前先去源服務器驗證緩存的有效性。
  • vary:vary是做爲響應頭由源服務器返回數據時添加的,其值就是當前請求的首部字段,如:Accept,User-Agent等,代理服務器會一併緩存Vary頭部的和頭部相關的內同。做用是告訴下游服務器如何正確匹配緩存

關於vary頭部

不一樣客戶端須要的內容多是不同的,若有的支持gzip,有的不支持。服務器提供的同一個接口,客戶端進行一樣的網絡請求,對於不一樣種類的客戶端可能須要的數據不一樣,服務器端的返回方式、返回數據也會不一樣,因此會經過Accept-Encoding,User-Agent等信息區別對待。

假如針對IE6Chrome須要使用不一樣的編碼方式傳輸,代理服務器中若是隻判斷同一個接口和請求,就頗有可能致使兩個瀏覽器拿到一樣的數據,毫無疑問會致使一些列問題,如亂碼等。同一個PC端和移動端應用也是如此,你提供給移動端和PC端的內容可能不一樣,代理服務器能夠經過判斷VaryUser-Agent來防止移動端誤用PC端緩存。Vary頭部的做用就體如今這裏,經過其包含的請求頭信息來有區別的匹配緩存。

具體參考:MDN-VaryHTTP請求的響應頭部Vary的理解

Expires(HTTP/1.0)

受限於客戶端時間,須要配合last-modified使用。且客戶端時間與服務器時間不一樣步可能會致使緩存失效。屬於HTTP/1的歷史遺留產物,現階段僅用於兼容。

Pragma: no-cache(HTTP/1.0)

同爲HTTP/1歷史遺留產物,通常只在爲了兼容HTTP/1的場合下使用。其在HTTP響應中的行爲並無被確切規範。若cache-control不存在的話,其行爲與cache-contorl: no-cache一致。

協商緩存

協商緩存生效,返回304(Not Modified)響應。若協商緩存失效,返回200和請求結果。

Last-Modified/If-Modified-Since/If-Unmodified-Since

若瀏覽器檢測到響應頭中的Last-Modified頭部,且強緩存未命中時,在下次資源請求時添加請求頭If-Modified-Since,其值對應Last-Modified的值,若服務器資源修改時間與If-Modified-Since不等,說明資源變更,協商緩存失效,返回新的資源。此外,If-Unmodified-Since顧名思義。

缺點Last-Modified只能以秒計時若在一秒內修改屢次,服務器是感知不到的,這會致使不能正確發送最新新資源到客戶端

E-Tag/If-Match/If-None-Match

服務器響應請求時,經過哈希算法計算出文件的一個惟一標識,並附帶在E-Tag響應頭中,只要資源變化,E-Tag就會從新生成。一樣的,在未命中強緩存且檢測到E-Tag的時候,瀏覽器就會爲請求附加If-Match/If-None-Match請求頭,其值對應E-Tag,若驗證成功則返回304。

缺點E-Tag的計算,會消耗服務器的性能,若資源頻繁變更,則服務器須要頻繁計算。

E-Tag和Last-Modified的比較

  1. E-Tag精度更高,但性能相對於Last-Modified稍遜一籌
  2. 兩者同時存在時優先考慮E-Tag

策略

  1. 對於頻繁變更的資源,咱們應該優先考慮使用協商緩存。雖不能減小HTTP請求,但可以顯著減少響應體積。甚至部分數據禁止緩存,永遠要獲取最新值,如股市動態等。
  2. 對於幾乎不變的資源,優先考慮強緩存。設置一個很是大的max-age等等。例如網站logo等。

緩存來源

Service Worker

Service Worker基於HTTPS,且能夠攔截全站請求以判斷資源是否緩存,若緩存命中則直接使用,不然使用fetch獲取最新資源。與瀏覽器內建緩存策略不一樣的是,Service Worker能夠自定義哪些資源須要緩存,如何匹配緩存,如何讀取緩存。其生命週期中主要使用:

  1. install 事件:抓取資源進行緩存

  2. activate 事件:遍歷緩存,清除過時的資源

  3. fetch 事件:攔截請求,查詢緩存或者網絡,返回請求的資源

具體再也不展開,有興趣能夠自行百度,或參考:MDN - Service Worker

Memory Cache

讀取速度極快,微秒級速度,但容量較小,且時效性差,通常關閉當前Tab標籤頁就會失效(隨進程釋放)。

Disk Cache

比Memory Cache容量大,可緩存的時間也更長。

相關文章
相關標籤/搜索