瀏覽器緩存機(jī)制有四個(gè)方面,它們按照獲取資源時(shí)請(qǐng)求的優(yōu)先級(jí)依次排列如下:
- Memory Cache
- Service Worker Cache
- HTTP Cache
- Push Cache
memory cache
memory cache: 內(nèi)存中的緩存,也是響應(yīng)速度最快的一種緩存,tab 關(guān)閉以后,內(nèi)存里的數(shù)據(jù)也將不復(fù)存在. Base64 格式的圖片,體積不大的 JS、CSS 文件,有較大地被寫(xiě)入內(nèi)存.
Memory Cache 優(yōu)先級(jí)大于 Disk Cache
disk cache
disk cache 將資源緩存到磁盤(pán)中,任何資源都能存儲(chǔ)到磁盤(pán)中.當(dāng)保存到內(nèi)存池中的數(shù)據(jù)達(dá)到一個(gè)程度時(shí),便會(huì)將數(shù)據(jù)保存到[硬盤(pán)]
Service Worker Cache
Service Worker 可以理解為一個(gè)代理服務(wù)器。可以做攔截客戶端的請(qǐng)求、向客戶端發(fā)送消息、向服務(wù)器發(fā)起請(qǐng)求等,以及最重要的離線資源緩存功能。它是一種獨(dú)立于主線程之外的 Javascript 線程。它脫離于瀏覽器窗體,因此無(wú)法直接訪問(wèn) DOM。
Push Cache
Push Cache 瀏覽器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情況下才會(huì)去詢問(wèn) Push Cache。
Push Cache 是一種存在于會(huì)話階段的緩存,當(dāng) session 終止時(shí),緩存也隨之釋放。
不同的頁(yè)面只要共享了同一個(gè) HTTP2 連接,那么它們就可以共享同一個(gè) Push Cache
HTTP Cache
分為強(qiáng)緩存和協(xié)商緩存。優(yōu)先級(jí)較高的是強(qiáng)緩存
強(qiáng)緩存
- 強(qiáng)緩存是利用 http 頭中的 Expires 和 Cache-Control 兩個(gè)字段來(lái)控制的
(1)public:所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)
(2)private:所有內(nèi)容只有客戶端可以緩存,Cache-Control的默認(rèn)取值
(3)no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過(guò)協(xié)商緩存來(lái)驗(yàn)證決定,
在瀏覽器使用緩存前,會(huì)往返對(duì)比ETag,如果ETag沒(méi)變,返回304,則使用緩存
(4)no-store:所有內(nèi)容都不會(huì)被緩存,即不使用強(qiáng)制緩存,也不使用協(xié)商緩存
(5)max-age=xxx (xxx is numeric):緩存內(nèi)容將在xxx秒后失效
協(xié)商緩存
| http response header key | http request headerkey |
|---|---|
| ETag(服務(wù)端返回的當(dāng)前資源的etag值) | If-None-Match(上一次服務(wù)器對(duì)于當(dāng)前資源返回的etag值) |
| Last-Modified(服務(wù)端返回的當(dāng)前資源的最后修改時(shí)間) | If-Modified-Since(上一次服務(wù)器對(duì)于當(dāng)前資源返回的最后修改時(shí)間) |
如果服務(wù)端提示緩存資源未改動(dòng)(Not Modified),資源會(huì)被重定向到瀏覽器緩存,這種情況下網(wǎng)絡(luò)請(qǐng)求對(duì)應(yīng)的狀態(tài)碼是 304。
ETag 只能作為 Last-Modified 的補(bǔ)充和強(qiáng)化存在.因?yàn)?/p>
- 我們編輯了文件,但文件的內(nèi)容沒(méi)有改變。服務(wù)端并不清楚我們是否真正改變了文件,它仍然通過(guò)最后編輯時(shí)間進(jìn)行判斷。因此這個(gè)資源在再次被請(qǐng)求時(shí),會(huì)被當(dāng)做新資源,進(jìn)而引發(fā)一次完整的響應(yīng)——不該重新請(qǐng)求的時(shí)候,也會(huì)重新請(qǐng)求。
- 當(dāng)我們修改文件的速度過(guò)快時(shí)(比如花了 100ms 完成了改動(dòng)),由于 If-Modified-Since 只能檢查到以秒為最小計(jì)量單位的時(shí)間差,所以它是感知不到這個(gè)改動(dòng)的——該重新請(qǐng)求的時(shí)候,反而沒(méi)有重新請(qǐng)求了。
- Etag 的生成過(guò)程需要服務(wù)器額外付出開(kāi)銷(xiāo),會(huì)影響服務(wù)端的性能。
Etag 的優(yōu)先級(jí)要高于 Last-Modified
CDN 緩存
全稱 即內(nèi)容分發(fā)網(wǎng)絡(luò)
可以理解成一個(gè)離和你距離很近的、方便從上面獲取完整的原始數(shù)據(jù)的服務(wù)器,為保證用戶可以從上面獲取到最新的內(nèi)容,它會(huì)定期和擁有原始內(nèi)容的服務(wù)器進(jìn)行同步更新。
這樣就可以以更快的速度和更好的連接質(zhì)量來(lái)獲取內(nèi)容。其次,CDN增強(qiáng)了整體的帶寬,原本一臺(tái)服務(wù)器變成多臺(tái)擁有相同內(nèi)容的服務(wù)器,用戶被分散到不同的服務(wù)器上面去進(jìn)行下載,平均每個(gè)用戶能夠分到的帶寬就會(huì)得到明顯的提高。同時(shí)也可以緩存資源,提升訪問(wèn)速度。