http緩存

緩存相關(guān)header

  • Expires

響應(yīng)頭,代表資源的過期時間

  • Cache-Control

請求/響應(yīng)頭,緩存控制字段,精確控制緩存策略

  • If-modified-Since

請求頭,資源最近修改時間,由瀏覽器告訴服務(wù)器

  • Last-Modified

響應(yīng)頭,資源最近修改時間,由服務(wù)器告訴瀏覽器

  • Etag

響應(yīng)頭,資源標識,由服務(wù)器告訴瀏覽器

  • If-None-Match

請求頭,緩存資源標識,由瀏覽器告訴服務(wù)器

配對使用的字段

  • If-modified-Since和Last-Modified
  • Etag和If-None-Match

從實際場景出發(fā),一點點完善緩存機制,來理解各個字段的意義

做一些約定,方便以后比較。

  • a.js 大小為10KB
  • 請求頭約定為1KB
  • 響應(yīng)頭約定為1KB

原始模型

  • 瀏覽器請求靜態(tài)資源a.js(請求頭1KB)
  • 服務(wù)器讀取磁盤文件,返回給瀏覽器。(文件+響應(yīng)頭 11KB)
  • 瀏覽器再次請求,服務(wù)器又重新讀取文件,返回給瀏覽器

消耗的流量與訪問次數(shù)正相關(guān)

瀏覽增加緩存機制

  • 瀏覽器第一次請求a.js,緩存a.js到本地磁盤 (1+10+1= 12KB)
  • 瀏覽器再次請求a.js,直接走瀏覽器緩存,不再向服務(wù)器發(fā)起請求 (0KB)

流量與訪問次數(shù)無關(guān),只有第一次請求會消耗瀏覽
缺點:服務(wù)器a.js更新后,瀏覽器也拿不到最新的資源

服務(wù)器和瀏覽器約定資源過期時間 Expires

  • 瀏覽器第一次請求靜態(tài)資源a.js(1KB)
  • 服務(wù)器把文件和文件緩存過期時間發(fā)給瀏覽器
  • 瀏覽器收到文件,記住了過期時間
  • 在過期時間之前,瀏覽器再次請求a.js,會直接使用上一次緩存的文件
  • 在過期時間之后,再次請求,會去請求服務(wù)器,服務(wù)器重新讀取文件返回給瀏覽器,同時告知瀏覽器新的過期時間。

缺點:緩存過期之后,服務(wù)器不管a.js有無變化,都會再次讀取a.js返回給瀏覽器

服務(wù)器告訴瀏覽器資源上次修改時間

  • 瀏覽器訪問a.js
  • 服務(wù)器返回a.js時,告訴瀏覽器a.js的上次修改時間Last-Modified及緩存過期時間Expires
  • 當過期時間之后請求a.js,會帶上 If-Modified-Since(等于上一次請求的Last-Modified)
  • 服務(wù)器比較請求頭里的If-Modified-Since和文件的上次修改時間
    • 如果一致,則告知瀏覽器可以繼續(xù)使用本地緩存(304)
    • 如果不一致,則讀取文件返回給瀏覽器,并帶上新的 Last-Modified及緩存過期時間Expires

缺點:Expires 過期控制不穩(wěn)定;Last-Modified 過期時間只能精確到秒(一秒內(nèi)文件變化頻繁,獲取不到最新的文件;可能存在文件未變化,但修改時間更新了的情況)。

增加相對時間的控制Cache-Contorl

為了兼容已有緩存方案,同時加入新的緩存方案。除了告訴瀏覽器Expires,還告訴一個相對時間 Cache-Control:max-age=10秒,含義是10秒內(nèi)使用緩存到瀏覽器的a.js。
瀏覽器先檢查Cache-Control,如果有,則以Cache-Control為準,忽略Expires。如果沒有Cache-Control則以Expires為準。

Cache-Control的常用設(shè)置值:

  • no-cache:不使用本地緩存,使用協(xié)商緩存
  • no-store:直接禁止瀏覽器緩存數(shù)據(jù),每次用戶請求該資源,都會向服務(wù)器發(fā)送請求,服務(wù)器都重新下載資源
  • public:可以被所有用戶緩存,包括終端用戶和CDN等中間代理服務(wù)器
  • private:只能被終端用戶的瀏覽器緩存,不允許中繼緩存服務(wù)器對其緩存

增加文件內(nèi)容對比,ETag 和 If-None-Match

a.js 內(nèi)容變了,Etag 才變。內(nèi)容不變,Etag 不變,可以理解為 Etag 是文件內(nèi)容的唯一 ID。

每次瀏覽器請求服務(wù)器的時候,都帶上If-None-Match字段,該字段的值就是上次請求 a.js 時,服務(wù)器返回給瀏覽器的 Etag。

  • 瀏覽器請求a.js.
  • 服務(wù)器返回a.js,同時告訴瀏覽器過期絕對時間Expires和相對時間Cache-Control:max-age=10),文件上次修改時間Last-Modified以及文件Etag。
  • 10秒內(nèi),瀏覽器再次請求,直接用本地緩存。
  • 10秒后,瀏覽器再次請求,帶上上次修改時間 If-Modified-Since和If-None-Match。
  • 服務(wù)器收到請求,發(fā)現(xiàn)有If-Modified-Since和If-None-Match。存在If-None-Match,則忽略If-Modified-Since。如果If-None-Match的值跟文件的Etag值相同,則告訴瀏覽器繼續(xù)使用本地緩存,否則返回新的文件及其他字段信息。

還存在的問題

無論是Expires還是Cache-Control,在緩存過期之前,瀏覽器都不會發(fā)請求詢問服務(wù)器,如果在這期間,服務(wù)器里的文件發(fā)生了變化,瀏覽器是感知不到的。

可以想象一下我們使用a.js的場景,一般都是輸入網(wǎng)址,訪問一個html文件,html文件里引入js、css、圖片等資源。
所以我們可以設(shè)置讓html文件不緩存,每次都拿到最新的html。然后如果js文件內(nèi)容有更新時,更新引用js的地方,可以通過版本號來區(qū)分,也可以通過hash值區(qū)分。使用webpack打包的話,借助插件可以很方便的處理。

<script src="http://test.com/a.js?version=0.0.1"></script>
<script src="http://test.com/a.【hash值】.js"></script>

強緩存和協(xié)商緩存
強緩存是利用Expires和Cache-Control兩個字段來控制的。
協(xié)商緩存是由服務(wù)器來確定緩存資源是否可用,主要通過Etag和If-None-Match、Last-Modified和If-Modified-Since這兩組字段來控制。

參考:
面試精選之http緩存
HTTP強緩存和協(xié)商緩存
前端緩存最佳實踐

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前端面試常問第二大問題是http緩存相關(guān)內(nèi)容。說真的,http緩存相關(guān)的細節(jié)比較多,并且 http 常用協(xié)議版本有...
    wdapp閱讀 63評論 0 0
  • 緩存相關(guān) header Expires 響應(yīng)頭,代表該資源的過期時間。 Cache-Control 請求/響應(yīng)頭,...
    mills_han閱讀 486評論 0 0
  • 無緩存,原始模型 瀏覽器請求靜態(tài)資源 a.js。(請求頭:1KB) 服務(wù)器讀取磁盤文件 a.js,返給瀏覽器。(1...
    明明你也一樣閱讀 585評論 0 0
  • 最近在看面試題的時候總會看到有一些關(guān)于Http緩存的題目,但是總是一知半解,不甚理解;尤其是Http頭信息中有一大...
    竿牘閱讀 900評論 0 0
  • 接著上篇《<計算機與網(wǎng)絡(luò)篇 > web緩存機制》,其細分出來四個緩存機制,而前端工程師能干預(yù)的也只有瀏覽器緩存這一...
    Max_Law閱讀 483評論 0 1

友情鏈接更多精彩內(nèi)容