作为前端应当了解的Web缓存知识
緩存優(yōu)點(diǎn)
通常所說的Web緩存指的是可以自動保存常見http請求副本的http設(shè)備。對于前端開發(fā)者來說,瀏覽器充當(dāng)了重要角色。除此外常見的還有各種各樣的代理服務(wù)器也可以做緩存。當(dāng)Web請求到達(dá)緩存時(shí),緩存從本地副本中提取這個副本內(nèi)容而不需要經(jīng)過服務(wù)器。這帶來了以下優(yōu)點(diǎn):
- 緩存減少了冗余的數(shù)據(jù)傳輸,節(jié)省流量
- 緩存緩解了帶寬瓶頸問題。不需要更多的帶寬就能更快加載頁面
- 緩存緩解了瞬間擁塞,降低了對原始服務(wù)器的要求。
- 緩存降低了距離延時(shí), 因?yàn)閺妮^遠(yuǎn)的地方加載頁面會更慢一些。
緩存種類
緩存可以是單個用戶專用的,也可以是多個用戶共享的。專用緩存被稱為私有緩存,共享的緩存被稱為公有緩存。
私有緩存
私有緩存只針對專有用戶,所以不需要很大空間,廉價(jià)。Web瀏覽器中有內(nèi)建的私有緩存——大多數(shù)瀏覽器都會將常用資源緩存在你的個人電腦的磁盤和內(nèi)存中。如Chrome瀏覽器的緩存存放位置就在:C:\Users\Your_Account\AppData\Local\Google\Chrome\User Data\Default中的Cache文件夾和Media Cache文件夾。
公有緩存
公有緩存是特殊的共享代理服務(wù)器,被稱為緩存代理服務(wù)器或代理緩存(反向代理的一種用途)。公有緩存會接受來自多個用戶的訪問,所以通過它能夠更好的減少冗余流量。
下圖中每個客戶端都會重復(fù)的向服務(wù)器訪問一個資源(此時(shí)還不在私有緩存中),這樣它會多次訪問服務(wù)器,增加服務(wù)器壓力。而使用共享的公有緩存時(shí),緩存只需要從服務(wù)器取一次,以后不用再經(jīng)過服務(wù)器,能夠顯著減輕服務(wù)器壓力。
事實(shí)上在實(shí)際應(yīng)用中通常采用層次化的公有緩存,基本思想是在靠近客戶端的地方使用小型廉價(jià)緩存,而更高層次中,則逐步采用更大、功能更強(qiáng)的緩存在裝載多用戶共享的資源。
緩存處理流程
而對于前端開發(fā)者來說,我們主要跟瀏覽器中的緩存打交道,所以上圖流程簡化為:
下面這張圖展示了某一網(wǎng)站,對不同資源的請求結(jié)果,其中可以看到有的資源直接從緩存中讀取,有的資源跟服務(wù)器進(jìn)行了再驗(yàn)證,有的資源重新從服務(wù)器端獲取。
注意,我們討論的所有關(guān)于緩存資源的問題,都僅僅針對GET請求。而對于POST, DELETE, PUT這類行為性操作通常不做任何緩存
新鮮度限值
HTTP通過緩存將服務(wù)器資源的副本保留一段時(shí)間,這段時(shí)間稱為新鮮度限值。這在一段時(shí)間內(nèi)請求相同資源不會再通過服務(wù)器。HTTP協(xié)議中Cache-Control 和 Expires可以用來設(shè)置新鮮度的限值,前者是HTTP1.1中新增的響應(yīng)頭,后者是HTTP1.0中的響應(yīng)頭。二者所做的事時(shí)都是相同的,但由于Cache-Control使用的是相對時(shí)間,而Expires可能存在客戶端與服務(wù)器端時(shí)間不一樣的問題,所以我們更傾向于選擇Cache-Control。
Cache-Control
下面我們來看看Cache-Control都可以設(shè)置哪些屬性值:
- max-age(單位為s)指定設(shè)置緩存最大的有效時(shí)間,定義的是時(shí)間長短。當(dāng)瀏覽器向服務(wù)器發(fā)送請求后,在max-age這段時(shí)間里瀏覽器就不會再向服務(wù)器發(fā)送請求了。
當(dāng)在5秒內(nèi)第二次訪問頁面時(shí),瀏覽器會直接從緩存中取得資源
- public 指定響應(yīng)可以在代理緩存中被緩存,于是可以被多用戶共享。如果沒有明確指定private,則默認(rèn)為public。
- private 響應(yīng)只能在私有緩存中被緩存,不能放在代理緩存上。對一些用戶信息敏感的資源,通常需要設(shè)置為private。
- no-cache 表示必須先與服務(wù)器確認(rèn)資源是否被更改過(依靠If-None-Match和Etag),然后再決定是否使用本地緩存。
如果上文中關(guān)于cache.png的處理改成下面這樣,則每次訪問頁面,瀏覽器都需要先去服務(wù)器端驗(yàn)證資源有沒有被更改。
- no-store 絕對禁止緩存任何資源,也就是說每次用戶請求資源時(shí),都會向服務(wù)器發(fā)送一個請求,每次都會下載完整的資源。通常用于機(jī)密性資源。
關(guān)于Cache-Control的使用,見下面這張圖(來自大額)
客戶端的新鮮度限值
Cache-Control不僅僅可以在響應(yīng)頭中設(shè)置,還可以在請求頭中設(shè)置。瀏覽器通過請求頭中設(shè)置Cache-Control可以決定是否從緩存中讀取資源。這也是為什么有時(shí)候點(diǎn)擊瀏覽器刷新按鈕和在地址欄回車,在NetWork模塊中看到完全不同的結(jié)果
Expires
不推薦使用Expires,它指定的是具體的過期日期而不是秒數(shù)。因?yàn)楹芏喾?wù)器跟客戶端存在時(shí)鐘不一致的情況,所以最好還是使用Cache-Control.
服務(wù)器再驗(yàn)證
瀏覽器或代理緩存中緩存的資源過期了,并不意味著它和原始服務(wù)器上的資源有實(shí)際的差異,僅僅意味著到了要進(jìn)行核對的時(shí)間了。這種情況被稱為服務(wù)器再驗(yàn)證。
- 如果資源發(fā)生變化,則需要取得新的資源,并在緩存中替換舊資源。
- 如果資源沒有發(fā)生變化,緩存只需要獲取新的響應(yīng)頭,和一個新的過期時(shí)間,對緩存中的資源過期時(shí)間進(jìn)行更新即可。
HTTP1.1推薦使用的驗(yàn)證方式是If-None-Match/Etag,在HTTP1.0中則使用If-Modified-Since/Last-Modified。
Etag與If-None-Match
根據(jù)實(shí)體內(nèi)容生成一段hash字符串,標(biāo)識資源的狀態(tài),由服務(wù)端產(chǎn)生。瀏覽器會將這串字符串傳回服務(wù)器,驗(yàn)證資源是否已經(jīng)修改,如果沒有修改,過程如下(圖片來自淺談Web緩存):
上文的demo中我們見到過服務(wù)器端如何驗(yàn)證Etag:
由于Etag有服務(wù)器構(gòu)造,所以在集群環(huán)境中一定要保證Etag的唯一性
If-Modified-Since與Last-Modified
這兩個是HTTP1.0中用來驗(yàn)證資源是否過期的請求/響應(yīng)頭,這兩個頭部都是日期,驗(yàn)證過程與Etag類似,這里不詳細(xì)介紹。使用這兩個頭部來驗(yàn)證資源是否更新時(shí),存在以下問題:
- 有些文檔資源周期性的被重寫,但實(shí)際內(nèi)容沒有改變。此時(shí)文件元數(shù)據(jù)中會顯示文件最近的修改日期與If-Modified-Since不相同,導(dǎo)致不必要的響應(yīng)。
- 有些文檔資源被修改了,但修改內(nèi)容并不重要,不需要所有的緩存都更新(比如代碼注釋)
關(guān)于緩存的更新問題,請大家看看這里張?jiān)讫埖幕卮?#xff0c;本文就不詳細(xì)展開了。
本文demo代碼如下:
轉(zhuǎn)載于:https://www.cnblogs.com/dojo-lzz/p/5515839.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的作为前端应当了解的Web缓存知识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Redis开发与运维》学习第三章
- 下一篇: RichTextBox 改变每行的字体颜