(精華)2020年8月18日 快取機制

愚公搬程式碼發表於2020-08-18

快取

1. 快取理解

  1. 快取定義:
  2. 瀏覽器在本地磁碟上將使用者之前請求的資料儲存起來,當訪問者再次需要改資料的時候無需再次傳送請求,直接從瀏覽器本地獲取資料
  3. 快取的好處:
  4. 減少請求的個數
  5. 節省頻寬,避免浪費不必要的網路資源
  6. 減輕伺服器壓力
  7. 提高瀏覽器網頁的載入速度,提高使用者體驗

2. 快取分類

  1. 強快取

  2. 不會向伺服器傳送請求,直接從本地快取中獲取資料

  3. 請求資源的的狀態碼為: 200 ok(from memory cache)

  4. 協商快取

  5. 向伺服器傳送請求,伺服器會根據請求頭的資源判斷是否命中協商快取

  6. 如果命中,則返回304狀態碼通知瀏覽器從快取中讀取資源

  7. 強快取 & 協商快取的共同點

  8. 都是從瀏覽器端讀取資源

  9. 強快取 VS 協商快取的不同點

    1. 強快取不發請求給伺服器
    2. 協商快取發請求給伺服器,根據伺服器返回的資訊決定是否使用快取

3. 快取使用示意圖

4. 快取中的header引數

1、瀏覽器預設快取時間

Chrome和Firefox對js、css之類的檔案,在記憶體中的快取時長,是:
  (訪問時間 - 該檔案的最後修改時間) ÷ 10
  例子:
  假設 7點0分 訪問的 5點0分修改的 index.html ,
  那麼快取時間為
  26060 ÷ 10 = 720 秒
  頁面快取時間為 720 秒

1、強快取的header引數


  1. expires:
  2. 這是http1.0時的規範;它的值為一個絕對時間的GMT格式的時間字串,如Mon, 10 Jun 2015 21:31:12 GMT,如果傳送請求的時間在expires之前,那麼本地快取始終有效,否則就會傳送請求到伺服器來獲取資源
  3. cache-control:max-age=number
  4. 這是http1.1時出現的header資訊,主要是利用該欄位的max-age值來進行判斷,它是一個相對值;資源第一次的請求時間和Cache-Control設定的有效期,計算出一個資源過期時間,再拿這個過期時間跟當前的請求時間比較,如果請求時間在過期時間之前,就能命中快取,否則就不行;
  5. cache-control常用的值(做一個簡單瞭解即可):
  6. no-cache: 不使用本地快取,需要使用協商快取。先與伺服器確認返回的響應是否被更改,如果之前的響應中存在Etag,那麼請求的額時候會與伺服器端進行驗證,如果資源為被更改則使用快取。
  7. no-store: 直接禁止遊覽器快取資料,每次使用者請求該資源,都會向伺服器傳送一個請求,每次都會下載完整的資源。
  8. public:可以被所有的使用者快取,包括終端使用者和CDN等中間代理伺服器。
  9. private:只能被終端使用者的瀏覽器快取,不允許CDN等中繼快取伺服器對其快取。
  10. 注意:當cache-control與Expires共存的時候cache-control的優先順序高

from memory cache與from disk cache詳解
https://blog.csdn.net/garrettzxd/article/details/80684880

他們是配合http快取的。 memory cache命中最快,但是它週期較短,base64的圖片,較小的js和css能夠有較大機率被寫進記憶體,這沒有確定的定論。 其他較大的js、css和圖片等會被直接寫進硬碟,進行快取。

儲存在磁碟空間的檔案通過在瀏覽器輸入 chrome://version/

2、協商快取的header引數


重點:協商快取都是由伺服器來確定快取資源是否可用的,所以客戶端與伺服器端要通過某種標識來進行通訊,從而讓伺服器判斷請求資源是否可以快取訪問

Last-Modified : 服務端生成後給客戶端的
If-Modified-Since:客戶端給服務端的, 只是變了一個名字

  • Last-Modified/If-Modified-Since:二者的值都是GMT格式的時間字串
  1. 瀏覽器第一次跟伺服器請求一個資源,伺服器在返回這個資源的同時,在respone的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也就不會改變,這是伺服器返回304時的response header
  4. 瀏覽器收到304的響應後,就會從快取中載入資源
  5. 如果協商快取沒有命中,瀏覽器直接從伺服器載入資源時,Last-Modified的Header在重新載入的時候會被更新,下次請求時,If-Modified-Since會啟用上次返回的Last-Modified值

Etag : 服務端生成後給客戶端的
If-None-Match : 客戶端給服務端的, 只是變了一個名字

  • Etag/If-None-Match
    1. 這兩個值是由伺服器生成的每個資源的唯一標識字串,只要資源有變化就這個值就會改變
    2. 其判斷過程與Last-Modified/If-Modified-Since類似

  • 既生Last-Modified何生Etag
    1. HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題
    2. 一些檔案也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認為這個檔案被修改了,而重新GET
    3. 某些檔案修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);
    4. 某些伺服器不能精確的得到檔案的最後修改時間。

  • 小結:
    • 利用Etag能夠更加準確的控制快取,因為Etag是伺服器自動生成或者由開發者生成的對應資源在伺服器端的唯一識別符號。

    • Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最後才決定是否返回304。

5. 強快取如何重新載入新的資源

  • 通過更新頁面中引用的資源路徑,讓瀏覽器主動放棄載入快取去載入新的資源
  • 示例:https://www.baidu.com/s?t=7aec0h3KB3Ba8lAbuyPg0AC0eDa59IvtDSmtMQBc6eW
  • 好處:
    • 每次檔案改變後query的值就會發生修改,當query值不同的時候也就是頁面引用的資源路徑不同。此時瀏覽器會主動載入新的資源。

快取示意圖

在這裡插入圖片描述

相關文章