聊一聊HTTP緩存

前言

  • 什麼是HTTP緩存?html

  • 爲何須要HTTP緩存,由於使用HTTP緩存能夠減小請求響應時間和避免網絡時延帶來的等待時間。chrome

  • 如何合理使用緩存,設置不一樣文件的緩存時間?瀏覽器

緩存的種類

緩存分爲兩種,Private cacheShared cache緩存

  • Private cache是針對單個用戶而言,一個例子就是本身的瀏覽器緩存,使用這些緩存實現了瀏覽器的前進/後退,而無需再次請求資源服務器

  • Shared Cache針對多個用戶,好比代理服務器,一個ISP (Internet Service Provider)或者公司都有代理服務器,用來緩存一些資源,供全部員工訪問,而沒必要再向互聯網發出請求,避免網絡延遲網絡

緩存控制

要清楚緩存控制,這裏要先分清兩個概念,一個叫作緩存存儲(Cache Storage),一個叫作緩存(Caching)ide

其實在中文裏面,可能直接都說成緩存,可是這樣不助於理解下面緩存控制的前兩種狀況。其實緩存存儲是一個實實在在的東西,而緩存只是它的一個動做spa

後來我又發現國人有強緩存協商緩存的說法,強緩存就是指Cache Storage會直接返回Cache的內容,協商緩存是指Cache Storage向原始服務器進行驗證,若是原始服務器返回304 Not ModifiedCache Storage才返回Cache的內容代理

淘寶網首頁, Chrome Dev Tools下觀察到的協商緩存(304)和強緩存 (from xxx cache)

強緩存和協商緩存驗證資源是否過時

上面一幅圖中,304 Not Modified表示使用了協商緩存,而from memory cachefrom disk cache則直接使用強緩存code

Chrome在某個版本以後將之前的from cache變成了from disk cachefrom memory cache,就跟名字同樣,緩存在磁盤中的內容即便在關閉了當前tab以後還能使用,可是緩存到內存的內容,當關閉tab或者瀏覽器,或者瀏覽器崩潰後,就消失了。可是memory cache加載速度更快,從上圖也能看出

關於強緩存和協商緩存,我沒發現這兩個詞的英文出處,可是這兩個詞理解起來更形象,因此下面的緩存控制狀況我也會用到這兩個詞

1. 不使用緩存存儲

能夠理解爲每次的請求都不通過Cache Storage,直接發給服務器,返回新的對象

Cache-Control: no-store
Cache-Control: no-cache, no-store, must-revalidate
複製代碼

2. 不直接使用緩存內容

Cache Storage會緩存內容,可是每次須要向服務器驗證資源是否過時,沒過時才能使用緩存,這就是304 Not Modified的狀況,也就是咱們所說的協商緩存

Cache-Control: no-cache
複製代碼

3. 公共緩存和私有緩存

例如告訴資源只能被Private Browser Cache緩存起來仍是同時也能被Public Proxy Server緩存起來

Cache-Control: private
Cache-Control: public
複製代碼

4. 強緩存過時控制

Cache-Control優先級高於Expired,前者是相對時間,後者是絕對時間;前者爲General Header的字段,後者爲Response Header的字段

Cache-Control: max-age=31536000 
Expires: Wed, 21 Oct 2015 07:28:00 GMT
複製代碼

5. 資源驗證

Cache-Control: must-revalidate
複製代碼

緩存驗證

緩存驗證發生在用戶刷新,或者響應頭中包含Cache-Control: must-revalidate的狀況

緩存驗證有兩種形式,均可以用來驗證文檔是否過時

  • 文檔的最後修改日期,響應頭Last-Modified字段,請求頭If-Modified-Since字段請求驗證
  • 對文檔當前版本的惟一標識,叫作entity tag,響應頭ETag字段,一般使用MD5 Hash實現,請求頭If-None-Match字段請求驗證

同時,緩存驗證有兩種驗證類型

  • 強驗證(strong validator),文檔對比一個字節一個字節地進行,嚴格對比
  • 弱驗證(weak validator),文檔只有語義不一樣才認爲是改變,例如一個HTML文檔也許只是裏面的廣告發生改變,或者是頁腳的日期發生改變,弱驗證會認爲它們仍是相同的

HTTP默認使用的是強驗證

須要注意的是,通常狀況下,Last-Modified字段只能做爲弱驗證,由於它的最小單位是秒,一秒內文檔可能改變2次,沒法作到標識每一次改變,若是使用它作強驗證,則須要明確知道不會發生這種狀況。固然,還有一些其餘的限制,具體的限制能夠看我下面的第4條RFC文檔參考,這裏就不細說了

ETag默認做爲強驗證,若是須要用它實現弱驗證比較困難,由於須要判斷文檔中不一樣元素的語義,確保語義變化時ETag的值才發生變化,而不是每次檢測到字節變化時就生成一個新的值

緩存驗證這部分建議有能力的同窗直接查看第4條RFC參考

條件緩存(響應頭增長Vary字段)

該字段指出了篩選條件,若是下一次到達Cache Storage的請求中的該條件與緩存時的該條件的值不同,則從新向真實server發請求,不然使用緩存,看下面這幅圖

在響應頭使用Vary字段條件驗證Content-Encoding

Vary字段一般會對User-Agent進行驗證,避免將移動端緩存的文檔直接發給桌面端請求的用戶,反之亦然

Vary: User-Agent
複製代碼

參考

  1. developer.mozilla.org/en-US/docs/…
  2. stackoverflow.com/questions/4…
  3. developer.mozilla.org/en-US/docs/…
  4. Weak and Strong Validators
相關文章
相關標籤/搜索