瀏覽器的localStorage和sessionStorage等不屬于瀏覽器的緩存概念,準(zhǔn)確的說應(yīng)該屬于“瀏覽器的本地存儲”不要講兩者混淆。
從緩存位置上來說一般有以下四種,依次是:
Memory Cache、Service Worker Cache、Disk Cache、Push Cache
- MemoryCache,是指存在內(nèi)存中的緩存。從優(yōu)先級上來說,它是瀏覽器最先嘗試去命中的一種緩存。從效率上來說,它是響應(yīng)速度最快的一種緩存。瀏覽器秉承的是“節(jié)約原則”,我們發(fā)現(xiàn),Base64 格式的圖片,幾乎永遠(yuǎn)可以被塞進(jìn) memory cache,這可以視作瀏覽器為節(jié)省渲染開銷的“自保行為”;此外,體積不大的 JS、CSS 文件,也有較大地被寫入內(nèi)存的幾率——相比之下,較大的 JS、CSS 文件就沒有這個待遇了,內(nèi)存資源是有限的,它們往往被直接甩進(jìn)磁盤。一旦我們關(guān)閉 Tab 頁面,內(nèi)存中的緩存也就被釋放了。
- Service Worker, 是一種獨(dú)立于主線程之外的 Javascript 線程。它脫離于瀏覽器窗體,因此無法直接訪問 DOM。這樣獨(dú)立的個性使得 Service Worker 的“個人行為”無法干擾頁面的性能,這個“幕后工作者”可以幫我們實現(xiàn)離線緩存、消息推送和網(wǎng)絡(luò)代理等功能。我們借助 Service worker 實現(xiàn)的離線緩存就稱為 Service Worker Cache。
- Disk Cache(HTTP Cache),Disk Cache 也就是存儲在硬盤中的緩存,讀取速度慢點(diǎn),但是什么都能存儲到磁盤中,比之 Memory Cache 勝在容量和存儲時效性上。在所有瀏覽器緩存中,Disk Cache 覆蓋面基本是最大的。它會根據(jù) HTTP Header 中的字段判斷哪些資源需要緩存,哪些資源可以不請求直接使用,哪些資源已經(jīng)過期需要重新請求。并且即使在跨站點(diǎn)的情況下,相同地址的資源一旦被硬盤緩存下來,就不會再次去請求數(shù)據(jù)。絕大部分的緩存都來自 Disk Cache,關(guān)于 HTTP 的協(xié)議頭中的緩存字段,我們會在下文進(jìn)行詳細(xì)介紹。它又分為強(qiáng)緩存和協(xié)商緩存。
- Push Cache,Push Cache 是指 HTTP2 在 server push 階段存在的緩存。
Push Cache 是緩存的最后一道防線。瀏覽器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情況下才會去詢問 Push Cache。
Push Cache(推送緩存) 是一種存在于會話階段的緩存,當(dāng) session 終止時,緩存也隨之釋放。
不同的頁面只要共享了同一個 HTTP2 連接,那么它們就可以共享同一個 Push Cache。
瀏覽器緩存的兩種方式
本地緩存階段(也稱強(qiáng)緩存):
先在本地查找該資源,如果有發(fā)現(xiàn)該資源,而且該資源還沒有過期,就使用這一個資源,完全不會發(fā)送http請求到服務(wù)器;
協(xié)商緩存階段(也稱弱緩存):
如果在本地緩存找到對應(yīng)的資源,但是不知道該資源是否過期或者已經(jīng)過期,則發(fā)一個http請求到服務(wù)器,然后服務(wù)器判斷這個請求,如果請求的資源在服務(wù)器上沒有改動過,則返回304,讓瀏覽器使用本地找到的那個資源;
Cache-Control
- max-age(單位為s)指定設(shè)置緩存最大的有效時間,定義的是時間長短。當(dāng)瀏覽器向服務(wù)器發(fā)送請求后,在max-age這段時間里瀏覽器就不會再向服務(wù)器發(fā)送請求了(強(qiáng)緩存)。
- s-maxage(單位為s)同max-age,只用于共享緩存(比如CDN緩存)。比如,當(dāng)s-maxage=60時,在這60秒中,即使更新了CDN的內(nèi)容,瀏覽器也不會進(jìn)行請求。也就是說max-age用于普通緩存,而s-maxage用于代理緩存。如果存在s-maxage,則會覆蓋掉max-age和Expires header。
- no-cache 指定不緩存響應(yīng),表明資源不進(jìn)行緩存,但是設(shè)置了 no-cache 之后并不代表瀏覽器不緩存,而是在獲取緩存前要向服務(wù)器確認(rèn)資源是否被更改。因此有的時候只設(shè)置 no-cache 防止緩存還是不夠保險,還可以加上 private 指令,將過期時間設(shè)為過去的時間。(no-cache 繞開了瀏覽器:我們?yōu)橘Y源設(shè)置了 no-cache 后,每一次發(fā)起請求都不會再去詢問瀏覽器的緩存情況,而是直接向服務(wù)端去確認(rèn)該資源是否過期,即走協(xié)商緩存的路線)(協(xié)商緩存)
- no-store 絕對禁止緩存,如果用了這個命令就是不會進(jìn)行緩存,每次請求資源都要從服務(wù)器重新獲取。(no-store 比較絕情,顧名思義就是不使用任何緩存策略。在 no-cache 的基礎(chǔ)上,它連服務(wù)端的緩存確認(rèn)也繞開了,只允許你直接向服務(wù)端發(fā)送請求、并下載完整的響應(yīng)。)
Expires(強(qiáng)緩存)
Expires字段的作用是,設(shè)定一個強(qiáng)緩存時間。在此時間范圍內(nèi),則從內(nèi)存(或磁盤)中讀取緩存返回。比如說將某一資源設(shè)置響應(yīng)頭為:Expires:new Date(“2022-7-30 23:59:59”);那么,該資源在2022-7-30 23:59:59 之前,都會去本地的磁盤(或內(nèi)存)中讀取,不會去服務(wù)器請求。但是,Expires已經(jīng)被廢棄了。對于強(qiáng)緩存來說,Expires已經(jīng)不是實現(xiàn)強(qiáng)緩存的首選。
因為Expires判斷強(qiáng)緩存是否過期的機(jī)制是:獲取本地時間戳,并對先前拿到的資源文件中的Expires字段的時間做比較。來判斷是否需要對服務(wù)器發(fā)起請求。這里有一個巨大的漏洞:“如果我本地時間不準(zhǔn)咋辦?”
是的,Expires過度依賴本地時間,如果本地與服務(wù)器時間不同步,就會出現(xiàn)資源無法被緩存或者資源永遠(yuǎn)被緩存的情況。所以,Expires字段幾乎不被使用了?,F(xiàn)在的項目中,我們并不推薦使用Expires,強(qiáng)緩存功能通常使用cache-control字段來代替Expires字段。
基于last-modified的協(xié)商緩存
基于last-modified的協(xié)商緩存實現(xiàn)方式是:
- 首先需要在服務(wù)器端讀出文件修改時間,
- 將讀出來的修改時間賦給響應(yīng)頭的last-modified字段。
- 最后設(shè)置Cache-control:no-cache
三步缺一不可。
注意圈出來的三行。
第一行,讀出修改時間。
第二行,給該資源響應(yīng)頭的last-modified字段賦值修改時間
第三行,給該資源響應(yīng)頭的Cache-Control字段值設(shè)置為:no-cache.(上文有介紹,Cache-control:no-cache的意思是跳過強(qiáng)緩存校驗,直接進(jìn)行協(xié)商緩存。)
還沒完。到這里還無法實現(xiàn)協(xié)商緩存
當(dāng)客戶端讀取到last-modified的時候,會在下次的請求標(biāo)頭中攜帶一個字段:If-Modified-Since。
基礎(chǔ)ETag的協(xié)商緩存
ETag就是將原先協(xié)商緩存的比較時間戳的形式修改成了比較文件指紋。
文件指紋:根據(jù)文件內(nèi)容計算出的唯一哈希值。文件內(nèi)容一旦改變則指紋改變。
我們來看一下流程↓文章來源:http://www.zghlxwxcb.cn/news/detail-814972.html
- 第一次請求某資源的時候,服務(wù)端讀取文件并計算出文件指紋,將文件指紋放在響應(yīng)頭的etag字段中跟資源一起返回給客戶端。
- 第二次請求某資源的時候,客戶端自動從緩存中讀取出上一次服務(wù)端返回的ETag也就是文件指紋。并賦給請求頭的if-None-Match字段,讓上一次的文件指紋跟隨請求一起回到服務(wù)端。
- 服務(wù)端拿到請求頭中的is-None-Match字段值(也就是上一次的文件指紋),并再次讀取目標(biāo)資源并生成文件指紋,兩個指紋做對比。如果兩個文件指紋完全吻合,說明文件沒有被改變,則直接返回304狀態(tài)碼和一個空的響應(yīng)體并return。如果兩個文件指紋不吻合,則說明文件被更改,那么將新的文件指紋重新存儲到響應(yīng)頭的ETag中并返回給客戶端
本文參考:
https://juejin.cn/post/7127194919235485733
https://www.jianshu.com/p/cb72dfb0f7b3文章來源地址http://www.zghlxwxcb.cn/news/detail-814972.html
到了這里,關(guān)于前端緩存機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!