摘要:我把緩存分為緩存存儲緩存對比兩部分。不過是的東西,現(xiàn)在默認瀏覽器均默認使用,所以它的作用基本忽略。當資源發(fā)送改變時,也隨之發(fā)生變化。關于版本號建議使用的形式而不是。
前幾天看到一篇關于緩存的文章徹底弄懂 Http 緩存機制 - 基于緩存策略三要素分解法,覺得很有意思,所以打算系統(tǒng)學習下Http緩存相關的知識。
我把緩存分為緩存存儲、緩存對比兩部分。
(一)基本概念 (1)緩存存儲基本概念
命中緩存速度對比
200 from cache? vs ?304 Not Modified?
思考:localStorage存儲
Pragma : no-cache ?http1.0時期的屬性? 為了兼容會使用
Expires:0 ?http1.0時期的屬性?
Cache-Control ?http1.1?中加入的新屬性,它有以下常用參數(shù):
Public/Private 私有緩存/共有緩存
no-cache:不建議使用本地緩存,但仍然會緩存到本地
no-store:不會在客戶端緩存任何數(shù)據(jù)
max-age:比較特殊,是一個混合屬性,替代了Expires的過期時間
舉個栗子:如果要設置客戶端不緩存,并兼容http1.0的方式可以這樣寫:
Pragma : no-cache Expires:0 Cache-Control:no-store
等價于
Pragma : no-cache // Pragma為了兼容http1.0 Cache-Control:max-age=0 // 去掉了Expires屬性(下面名詞解釋會說到為什么被去掉),合并到max-age中,
(2)緩存對比名詞解釋:
私有緩存:《HTTP權威指南》里面講到了私有緩存的一種就是在瀏覽器里面輸入 ?about:cache? 可以查看自己瀏覽器緩存的內容,會給出一個顯示了緩存內容“磁盤緩存統(tǒng)計”頁面,這個可以看看還挺有意思,能展示不少信息
Expires:過時期限值,GMT格式,是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數(shù)據(jù),而無需再次請求。不過Expires 是HTTP 1.0的東西,現(xiàn)在默認瀏覽器均默認使用HTTP 1.1,所以它的作用基本忽略。Expires 的一個缺點就是,返回的到期時間是服務器端的時間,這樣存在一個問題,如果客戶端的時間與服務器的時間相差很大(比如時鐘不同步,或者跨時區(qū)),那么誤差就很大,所以在HTTP 1.1版開始,使用Cache-Control: max-age=秒替代。
Last-Modified ?http1.0時期屬性? 現(xiàn)在仍在使用
ETag(Entity Tag) ?http1.1時期新加屬性?,使用inode+mtime(以下有解釋)來計算。根據(jù)實體內容生成的一段hash字符串(類似于MD5或者SHA1之后的結果),可以標識資源的狀態(tài)。 當資源發(fā)送改變時,ETag也隨之發(fā)生變化。
2.1為什么用http1.1新推出了ETag名詞解釋:
inode :包含文件的元信息,包括以下內容文件的字節(jié)數(shù)、文件擁有者的User ID、文件的Group ID
文件的讀、寫、執(zhí)行權限
文件的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指文>件內容上一次變動的時間,atime指文件上一次打開的時間。
鏈接數(shù),即有多少文件名指向這個inode、 文件數(shù)據(jù)block的位置
mtime:指文件內容上一次變動的時間
某些服務器不能精確得到文件的最后修改時間, 這樣就無法通過最后修改時間來判斷文件是否更新了。
某些文件的修改非常頻繁,在秒以下的時間內進行修改. Last-Modified只能精確到秒。
一些文件的最后修改時間改變了,但是內容并未改變。 我們不希望客戶端認為這個文件修改了。
2.2ETag有哪些問題ETag也有他自己的問題,所以經(jīng)常在使用中會關閉ETag。舉例來說,同一個文件在不同物理機上的inode是不同的,這就導致了在分布式的Web系統(tǒng)中,當訪問落在不同的物理機上時會返回不同的ETag,進而導致304失效,降級為200請求。解決辦法也有從ETag算法中剝離inode,只是使用mtime,但是這樣實際上和Last-Modified就一樣了。當然你也可以額外的做一些改進,使ETag對靜態(tài)資源的算法也是通過hash計算的。不過由于一般我們會使用CDN技術,因此集群部署中的ETag問題并不會造成太大的影響,所以折騰的人也不太是很多。 ?參考:這篇文章hefangshi同學的回答
(二)命中緩存速度對比圖片描述
引一張《HTTP權威指南》中的一張圖,可以看出命中緩存過程:
1.1緩存命中優(yōu)先級緩存命中 > 緩存再驗證成功 > 緩存未命中 = 緩存再驗證失?。?/p>
1.2緩存再驗證成功Cache-Control http1.1 > Expires > Pragma http1.0來決定是否 (200 from cache)
根據(jù)Last-Modified http1.0 和 ETaghttp1.1 來驗證是否返回 (304 Not Modified) 兩者都有,就必須同時驗證,并且兩者都滿足才會返回304;
圖片描述
服務端響應頭 Last-Modified 與 客戶端請求頭 If-Modified-Since 對應
服務端響應頭 ETag 與 客戶端請求頭 If-None-Match
(三) 200 from cache vs 304 Not Modified為什么有時候明明命中了緩存,控制臺中Status顯示的不是 200 from cache??原來是瀏覽器的原因:
觸發(fā) 200 from cache:
直接點擊鏈接訪問
輸入網(wǎng)址按回車訪問
二維碼掃描
觸發(fā) 304 Not Modified:
刷新頁面時觸發(fā)
設置了長緩存、但 Entity Tags 沒有移除時觸發(fā)
二者怎么選擇毫無疑問選擇可以盡量多的命中緩存,然后靠更新靜態(tài)文件的版本號來使緩存失效。關于版本號建議使用 file.xxx.js 的形式而不是 file.js?v=xxx。
可以看這兩篇文章有講述原因:
Best Practices for Speeding Up Your Web Site
大公司里怎樣開發(fā)和部署前端代碼
(四)思考在研究緩存問題的時候,知乎上看到這個問題:靜態(tài)資源(JS/CSS)存儲在localStorage有什么缺點?為什么沒有被廣泛應用??,看了大神們的答案主要是維護成本實在過高,如果真的速度超快,這點可以忽略,值得花時間研究,但是如果讀取再執(zhí)行的速度可能會比瀏覽器直接304性能要低,就完全沒有必要使用這種方式了。
(五 )參考文章:配置錯誤產(chǎn)生的差距:200 OK (FROM CACHE) 與 304 NOT MODIFIED?
http://www.benhallbenhall.com/2012/03/http-codes-200-from-cache-304/
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/61846.html
摘要:整個請求響應鏈的緩存機制必須遵循的特別指令?;镜木彺鏅C制就是由這些參數(shù)形成的。如果此文章中有什么問題的話,煩請一定要指出,謝謝參考資料緩存機制淺析移動端加載性能優(yōu)化淺談瀏覽器的緩存機制 之前對http的緩存知識一知半解,只能說出個大概。和同事交流這塊內容時稍一深入探討就捉襟見肘,自慚形穢。故痛定思痛,花了一兩天時間去研究了下這塊內容,寫下這篇筆記方便以后的查詢與修正。 首先介紹下和緩...
閱讀 2747·2021-09-24 09:47
閱讀 4375·2021-08-27 13:10
閱讀 2990·2019-08-30 15:44
閱讀 1289·2019-08-29 12:56
閱讀 2598·2019-08-28 18:07
閱讀 2619·2019-08-26 14:05
閱讀 2569·2019-08-26 13:41
閱讀 1271·2019-08-26 13:33