[深刻07] 瀏覽器緩存機制(http緩存機制)

導航

[深刻01] 執行上下文
[深刻02] 原型鏈
[深刻03] 繼承
[深刻04] 事件循環
[深刻05] 柯里化 偏函數 函數記憶
[深刻06] 隱式轉換 和 運算符
[深刻07] 瀏覽器緩存機制(http緩存機制)
[深刻08] 前端安全
[深刻09] 深淺拷貝
[深刻10] Debounce Throttle
[深刻11] 前端路由
[深刻12] 前端模塊化
[深刻13] 觀察者模式 發佈訂閱模式 雙向數據綁定
[深刻14] canvas
[深刻15] webSocket
[深刻16] webpack
[深刻17] http 和 https
[深刻18] CSS-interview
[react] Hooks前端

[部署01] Nginx
[部署02] Docker 部署vue項目
[部署03] gitlab-CIvue

[源碼-webpack01-前置知識] AST抽象語法樹
[源碼-webpack02-前置知識] Tapable
[源碼-webpack03] 手寫webpack - compiler簡單編譯流程react

緩存的重要性

  • 一個優秀的緩存策略,能夠縮短網頁請求資源的距離,減小延遲,緩存文件能夠重複利用因此還能夠減小帶寬,下降網路負荷

瀏覽器緩存

  • 瀏覽器啓用緩存的優勢:減小頁面加載時間,減小服務器負載
  • 瀏覽器是否使用緩存,緩存多久,是由服務器控制的
    • 即服務器響應的 響應頭 中,某些字段指明瞭緩存的關鍵信息
  • 通用首部字段
    • 請求和響應都能用的字段
    • Cache-Control
  • 請求首部字段
    • If-None-Match
    • If-Modified-Since
  • 響應首部字段
    • ETag
  • 實體首部字段
    • Expires
    • Last-Modified
  • 瀏覽器緩存的分類
    • 強緩存協商緩存

強緩存

  • ExpiresCache-Control
  • 返回的狀態碼 200
  • network => size => 會顯示 from-cache (from-disk-cache),(from-memory-cache)
  • 強緩存的實現:經過( Expires ) 或者 ( Cache-Control ) 這兩個 ( http response header ) 來實現的,他們用都是用來表示資源在客服端存在的 有效期

Expires

  • http1.0提出,響應頭中的一個字段,絕對時間,用GMT格式的字符串表示
  • 注意:expires是和瀏覽器本地的時間作對比,是一個絕對時間點,是一個GMT時間
  • Expires是優化中最理想的狀況,由於它根本不會產生請求,因此後端也就無需考慮查詢快慢
  • Expires的原理
Expires的原理

1. 瀏覽器第一次向服務器請求資源,瀏覽器在請求資源的同時,在responder響應頭中加上Expires字段
2. 瀏覽器在接收到這個資源後,將這個資源和全部response header一塊兒緩存起來
   - 因此,緩存命中的請求返回的header並非來自服務器,而是來自以前緩存的header
3. 瀏覽器再次請求這個資源時,先從緩存中尋找,找到這個資源後,拿出Expires跟當前的請求時間作比較
   - 若是當前請求時間,在Expires指定的時間以前,就能命中強緩存,不然不能
   - 注意:Expires是和瀏覽器本地時間做對比
4. 若是未命中緩存,則瀏覽器直接從服務器獲取資源,並更新response header中的Expires
複製代碼
  • expires是較老的強緩存管理header,是服務器返回的一個絕對時間,在服務器時間與客服端時間相差較大時,Expires緩存管理容易出問題(好比:隨便修改客戶端時間,就能影響命中結果),因此在http1.1中,提出了新的header => Cache-Control,一個相對時間,以秒爲單位,用數值表示

Cache-Control

  • http1.1提出,響應頭中的一個字段,相對時間,以秒爲單位,用數值表示
  • 注意:Cache-Control也是和瀏覽器本地時間作對比,以秒爲單位的時間段
  • Cache-Control能夠指定:publicprivate
    • private表示該資源僅僅屬於發出請求的最終用戶,這將禁止中間服務器(如代理服務器)緩存此類資源,對於包含用戶我的信息的文件,能夠設置private
    • public容許全部服務器緩存該資源
    • no-cache:使用協商緩存
    • no-store:不使用緩存
    • max-age: 123123 // 一個時間段,單位是s
  • Cache-control: no-cache,private,max-age=123123
  • Cache-Control的原理
Cache-Control的原理

1. 瀏覽器第一次向服務器請求資源,服務器在返回資源的同時,在responder的header中加上Cache-Control字段
2. 瀏覽器在接收到這個資源後,會將這個資源和全部的response header一塊兒緩存起來
   - 因此,緩存命中的請求返回的header並非來自服務器,而是來自以前緩存的header
3. 瀏覽器再次請求這個資源時,先從緩存中尋找,找到這個資源後,拿出Cache-Control和當前請求的時間作比較
   - 若是當前請求時間,在Cache-Control表示的時間段內,就能命中強緩存,不然不能
4. 若是緩存未命中,則瀏覽器直接從服務器獲取資源,並更新response header中的 Cache-Control
複製代碼

強緩存Expires和Cache-Control總結

  • Expires和Cache-Control能夠開啓一個,也能夠同時開啓
  • 當Expires和Cache-Control同時開啓時,Cache-Control優先級高於Expires
  • Cache-Control能夠指定private和public,表示是否容許中間服務器緩存該資源
  • expires是一個用GMT時間表示的時間點,Cach-Control是用秒錶示的時間段,都是和瀏覽器本地時間作對比

協商緩存

  • Last-Modified(If-Modified-Since)ETag(If-None-Match)
  • 返回狀態碼 304
  • 協商緩存的原理:當瀏覽器對某個資源的請求沒有命中強緩存,就會發一個請求到服務器,驗證協商緩存是否命中,若是協商緩存命中,請求響應返回的http狀態爲304,而且會顯示一個Not Modified的字符串表示資源未被修改
  • modified: 是修改的意思

Last-Modified 和 If-Modified-Since

  • Last-Modified和If-Modified-Since都是根據 服務器時間 返回的header
  • 響應頭:Last-Modified
  • 請求頭:If-Modified-Since
  • 原理
Last-Modified If-None-Match

1. 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上Last-Modified的header
   - 這個header表示這個資源在服務器上的最後修改時間

2. 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-Modified-Since的header
   - 這個header的值就是上一次請求時返回的Last-Modified的值

3. 服務器再次收到資源請求時,根據瀏覽器傳過來If-Modified-Since和資源在服務器上的最後修改時間判斷資源是否有變化
   - 若是沒有變化則返回304 Not Modified,可是不會返回資源內容;
   - 若是有變化,就正常返回資源內容。
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   // 當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header
   // 由於既然資源沒有變化,那麼Last-Modified也就不會改變
 
4. 瀏覽器收到304的響應後,就會從緩存中加載資源

5. 若是協商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modified Header在從新加載的時候會被更新
   - 下次請求時,If-Modified-Since會啓用上次返回的Last-Modified值
複製代碼

ETag 和 If-None-Match

  • 只要資源有變化ETag這個字符串就不同,和修改時間沒有關係,因此很好的補充了Last-Modified的問題
  • 響應頭:ETag
  • 請求頭:If-None-Match
  • 原理
ETag 和 If-None-Match

1. 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上ETag的header
   - 這個header是服務器根據當前請求的資源生成的一個惟一標識,這個惟一標識是一個字符串
   - 只要資源有變化這個串就不一樣,跟最後修改時間沒有關係,因此能很好的補充Last-Modified的問題

2. 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-None-Match的header,
   - 這個header的值就是上一次請求時返回的ETag的值

3. 服務器再次收到資源請求時,根據瀏覽器傳過來If-None-Match而後再根據資源生成一個新的ETag
   - 若是沒有變化則返回304 Not Modified,可是不會返回資源內容
   - 若是有變化,就正常返回資源內容。
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   // 與Last-Modified不同的是,當服務器返回304 Not Modified的響應時
   // 因爲ETag從新生成過,response header中還會把這個ETag返回,即便這個ETag跟以前的沒有變化

4. 瀏覽器收到304的響應後,就會從緩存中加載資源。
複製代碼

Last-Modified(If-Modified-Since) 和 ETag(If-None-Match) 的區別

  • ETag的優點
    • ETag和Last-Modified很是類似,都是用來判斷一個參數,從而決定是否啓用緩存。
    • 可是ETag相對於Last-Modified也有其優點,能夠更加準確的判斷文件內容是否被修改,從而在實際操做中實用程度也更高。

強緩存和協商緩存的區別

  • 協商緩存跟強緩存不同,強緩存不發請求到服務器,因此有時候資源更新了瀏覽器還不知道,可是協商緩存會發請求到服務器,因此資源是否更新,服務器確定知道。
  • 大部分web服務器都默認開啓協商緩存,並且是同時啓用Last-Modified,If-Modified-Since和ETag、If-None-Match
  • Last-Modified,If-Modified-Since和ETag、If-None-Match通常都是同時啓用,這是爲了處理Last-Modified不可靠的狀況
  • // 分佈式系統裏多臺機器間文件的Last-Modified必須保持一致,以避免負載均衡到不一樣機器致使比對失敗
  • // 分佈式系統儘可能關閉掉ETag(每臺機器生成的ETag都會不同)

瀏覽器緩存判斷的流程

  1. 第一次正常請求後,緩存了資源和全部header的前提下
  2. 在資源緩存後,在緩存過時失效以前,若是再次請求該資源,默認先檢查強緩存
    • 強緩存命中,則直接讀取
    • 未命中強緩存,則發送請求到服務器,再檢查是否命中協商緩存
  3. 未命中強緩存,再發請求到服務器檢查是否命中協商緩存
    • 協商緩存命中,則告訴瀏覽器仍是能夠從緩存讀取
    • 未命中協商緩存,才從服務器返回最新的資源

juejin.im/post/5b9346…webpack

相關文章
相關標籤/搜索