1. 程式人生 > 實用技巧 >HTTP快取(Cache-Control、Expires 、ETag)

HTTP快取(Cache-Control、Expires 、ETag)

HTTP快取

HTTP快取( ETag、Cache-Control)——谷歌開發者
HTTP快取有利於web效能優化

Cache-Control

例子

假設我們首頁有一個請求,請求js檔案
<script src="./main.js"></script>
如何讓CSS和JS請求速度加快?

此時開啟首頁

發現這個檔案大小為279KB,使用時間為382ms

如果再次重新整理首頁,那麼這個檔案還會被再次請求一次。那麼如何重複利用之前獲取的資源而不用反覆請求呢?答案是HTTP快取,這是效能優化的一個重要方面。

接下來在響應裡設定響應頭
Cache-Control: max-age=30


重新整理兩次首頁


第二次的時間為0
響應頭中的Cache-Control: max-age=30表示客戶端將這個快取最多 儲存30 秒,30秒後再次請求檔案將會再次下載。

即:
設定這個響應頭之後,瀏覽器請求時發現是相同的URL,瀏覽器直接從記憶體裡返回已經快取的main.js,沒有向伺服器發出請求

問題

  1. 為什麼首頁不設定Cache-Control呢?
    如果首頁快取,重新整理首頁的時候根本不會請求伺服器,那麼如果伺服器更新了程式碼,瀏覽器將沒有辦法接收到新的版本。一般首頁,HTML不要設定Cache-Control。js和css要設定久一點例如10年,即一直保留有快取。
  2. 那麼js和css更新了怎麼辦?
    瀏覽器請求時發現是相同的URL才使用快取,那麼可以設定查詢引數,例如第二個版本的js可以寫<script src="./main.js?v=2"></script>
    ,來保證URL的不同,重新獲取新的js檔案。這樣即可以快取很久,又可以隨時更新

    例如知乎的網頁裡的請求:

總結

通過網路獲取內容既速度緩慢又開銷巨大。較大的響應需要在客戶端與伺服器之間進行多次往返通訊,這會延遲瀏覽器獲得和處理內容的時間,還會增加訪問者的流量費用。因此,快取並重複利用之前獲取的資源的能力成為效能優化的一個關鍵方面。

好在每個瀏覽器都自帶了 HTTP 快取實現功能。您只需要確保每個伺服器響應都提供正確的 HTTP
標頭指令,以指示瀏覽器何時可以快取響應以及可以快取多久。

Expires

  1. Expires 是以前用來控制快取的http頭,Cache-Control是新版的API。
  2. 現在首選Cache-Control。
  3. 如果在Cache-Control響應頭設定了 "max-age" 或者 "s-max-age" 指令,那麼 Expires 頭會被忽略。
  4. 響應頭設定方式:
    Expires: Wed, 21 Oct 2015 07:28:00 GMT
  5. Expires 響應頭包含日期/時間, 即在此時候之後,響應過期。

注意: 因為過期標準的時間用的是本地時間,所以不靠譜,所以要遊俠使用Cache-Control代替Expires

區別

  1. Cache-Control設定時間長度
  2. Expires 設定時間點

詳細:Expires - HTTP | MDN

MD5

MD5是訊息摘要演算法。用於確保資訊傳輸完整一致。

具體作用這樣

接受一個String 或 Buffer,返回一個固定的String

如果接受的String改變,那麼返回的String也會改變
例如將1.txt中的其中一個1改為0,那麼返回值如下

可見返回至完全改變了
這個特性可以用來判斷兩次資訊傳輸是否完整一致

ETag

例子:

例如我們請求一個js檔案。
設定一個ETag響應頭

設定的ETage響應頭為這個JS檔案的MD5值
檢視響應:

那麼:下一次請求這個JS的時候,瀏覽器會把上一次響應的那個ETage的值放到If-None-Match裡面,如圖:

這樣做的作用是:如果請求和響應的MD5一樣,說明不需要重新下載這個js檔案。這時我們修改程式碼:

如果MD5一樣,說明檔案沒改過,那麼返回304

304 Not Modified
HTTP 304 未改變說明無需再次傳輸請求的內容,也就是說可以使用快取的內容。

HTTP 304沒有響應體,因為不需要下載響應內容,直接用快取就行了

ETag與 Cache-Control的區別

假設我們請求兩個檔案,CSS檔案使用Cache-Control快取,js檔案使用ETag。
程式碼如下:

兩個請求區別:

所以:

    • 由於CSS的請求是用快取(Cache-Control)的,所以直接不發請求
    • 而js用的ETag,有請求也有響應,只不過如果MD5一樣,那麼就不下載響應體

轉自https://segmentfault.com/a/1190000016705679