瀏覽器強緩存和協商緩存

緩存機制

  1. 瀏覽器發送請求前,根據請求頭的expires和cache-control判斷是否命中強緩存策略,若是命中,直接從緩存獲取資源,並不會發送請求。若是沒有命中,進入下一步。
  2. 沒有命中強緩存規則,瀏覽器會發送請求,根據請求頭的last-modified和etag判斷是否命中協商緩存,若是命中,直接從緩存中獲取資源。若是沒有命中,進入下一步。
  3. 若是前兩步都沒有命中,則直接從服務器中獲取資源。

1. 強緩存

不會向服務器發送請求,直接從緩存中讀取資源css

三種狀況:nginx

  1. 第一次請求,不存在緩存結果和緩存標識,直接向服務器發送請求
  2. 存在緩存標識和緩存結果,可是緩存結果已經失效,則使用協商緩存
  3. 存在該緩存結果和緩存標識,且該結果還沒有失效,強制緩存生效,直接返回該結果

當瀏覽器向服務器發起請求時,服務器會將緩存規則放入HTTP響應頭中返回給瀏覽器,控制強緩存的字段分別是Expires和Cache-Control,其中Cache-Control優先級比Expires高。segmentfault

Expires

Expires用來指定資源到期時間,Expires是服務器響應信息頭字段,在響應http請求時告訴瀏覽器在過時時間以前瀏覽器能夠直接從瀏覽器緩存中,而無需再次請求。瀏覽器

Cache-Control

Cache-Control是最重要的規則,主要用於控制網頁緩存,主要取值爲:緩存

  • public:全部內容都將被緩存(客戶端和代理服務器均可緩存)
  • private:全部內容只有客戶端能夠緩存,Cache-Control的默認取值
  • no-cache:客戶端緩存內容,可是是否使用緩存則須要通過協商緩存來驗證決定
  • no-store:全部內容都不會被緩存,即不使用強制緩存,也不使用協商緩存
  • max-age=xxx (xxx is numeric):緩存內容將在xxx秒後失效

須要注意的是,no-cache這個名字有一點誤導。設置了no-cache以後,並非說瀏覽器就再也不緩存數據,只是瀏覽器在使用緩存數據時,須要先確認一下數據是否還跟服務器保持一致,也就是協商緩存。而no-store才表示不會被緩存,即不使用強制緩存,也不使用協商緩存bash

nginx設置

強緩存須要服務器設置Expires和Cache-Control服務器

// 設置一年的緩存時間

location ~ .*\.(ico|svg|ttf|eot|woff)(.*) {
  proxy_cache               pnc;
  proxy_cache_valid         200 304 1y;
  proxy_cache_valid         any 1m;
  proxy_cache_lock          on;
  proxy_cache_lock_timeout  5s;
  proxy_cache_use_stale     updating error timeout invalid_header http_500 http_502;
  expires                   1y;
}

複製代碼

from disk cache 和 from memory cache

網絡請求的size會出現三種狀況網絡

  1. from memory cache (內存緩存)
  2. from disk cache (磁盤緩存)
  3. 100KB (資源數值大小)
  • 100KB 狀態碼爲200, 直接從服務器下載最新資源
  • from memory cache 不請求網絡資源,資源在內存當中,通常腳本,字體,圖片會存放在內存當中
  • from disk cache 不請求網絡資源,在磁盤當中,通常非腳本會存在內存當中,如css

http狀態碼爲304 表示報文大小,請求服務端發現資源沒有更新,使用本地資源svg

2. 協商緩存

協商緩存就是強緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程。函數

  • 協商緩存生效,返回304 和 Not Modified

  • 協商緩存失效,返回200 和 請求結果

2.1 Last-Modified和If-Modified-Since

  1. 瀏覽器首先發送一個請求,讓服務端在response header中返回請求的資源上次更新時間,就是last-modified,瀏覽器會緩存下這個時間。
  2. 而後瀏覽器再下次請求中,request header中帶上if-modified-since:[保存的last-modified的值]。根據瀏覽器發送的修改時間和服務端的修改時間進行比對,一致的話表明資源沒有改變,服務端返回正文爲空的響應,讓瀏覽器中緩存中讀取資源,這就大大減少了請求的消耗。

2.2 ETag和If-None-Match

etag是http協議提供的若干機制中的一種Web緩存驗證機制,而且容許客戶端進行緩存協商。生成etag經常使用的方法包括對資源內容使用抗碰撞散列函數,使用最近修改的時間戳的哈希值,甚至只是一個版本號。 和last-modified同樣

  • 瀏覽器會先發送一個請求獲得etag的值,而後再下一次請求在request header中帶上if-none-match:[保存的etag的值]。
  • 經過發送的etag的值和服務端從新生成的etag的值進行比對,若是一致表明資源沒有改變,服務端返回正文爲空的響應,告訴瀏覽器從緩存中讀取資源。

etag可以解決last-modified的一些缺點,可是etag每次服務端生成都須要進行讀寫操做,而last-modified只須要讀取操做,從這方面來看,etag的消耗是更大的。

兩者對比

  • 精確度上:Etag要優於Last-Modified。
  • 優先級上:服務器校驗優先考慮Etag。
  • 性能上:Etag要遜於Last-Modified

3. 用戶行爲對瀏覽器緩存的影響

  1. 打開網頁,地址欄輸入地址: 查找 disk cache 中是否有匹配。若有則使用;如沒有則發送網絡請求。
  2. 普通刷新 (F5):由於 TAB 並無關閉,所以 memory cache 是可用的,會被優先使用(若是匹配的話)。其次纔是 disk cache。
  3. 強制刷新 (Ctrl + F5):瀏覽器不使用緩存,所以發送的請求頭部均帶有 Cache-control:no-cache(爲了兼容,還帶了 Pragma:no-cache),服務器直接返回 200 和最新內容。

原文地址

相關文章
相關標籤/搜索