博客 / 詳情

返回

由瀏覽器緩存機制引起的思考

不管三七二十一,先丟一張流程圖,然後看個一分鐘。

有了大致的流程印象之後,我就來補充説明一下大概流程:
PS:面試的時候可以按大概流程來説。
當我們進入頁面或刷新頁面時,瀏覽器會加載資源。
此時,瀏覽器會檢查是否有強緩存,即判斷是否有expires或者cache-control(cache-control優先級更高)。
如果有,則查看是否過期,未過期則從緩存讀取資源進行加載。
如果過期,則判斷瀏覽器是否有協商緩存。協商緩存標誌包括了Last-Modify/If-Modify-SinceETag/If-None-Match(ETag優先級更高)。
如果沒有,則直接向服務器發送請求獲取資源。
如果有,則向服務器發送協商緩存標誌,服務器根據瀏覽器發送過來的標誌判斷是否與服務器上相同。
若相同,則服務器返回 304,並且不會返回資源內容,瀏覽器從協商緩存讀取資源進行加載。
若不同,則服務器返回200,並返回資源內容給瀏覽器加載。

講完了大概流程,就需要來補充細節啦。

瀏覽器緩存分為強緩存和協商緩存

強緩存

強緩存分為memory cachedisk cache,如下表所示。

memory cache disk cache
定義 即內存緩存,將資源緩存在內存中 即磁盤緩存,將資源緩存在磁盤中
相同點 能存放JS,CSS,圖片等內容 能存放JS,CSS,圖片等內容
不同點 退出進程時數據會被清除 退出進程時數據不會被清除

三級緩存原理

瀏覽器先在內存中查找資源,如果有,直接加載。
如果內存中不存在,則在磁盤中查找,如果有直接加載。
如果磁盤中也沒有,那麼就進行網絡請求。
請求獲取的資源緩存到硬盤和內存。

協商緩存

當強緩存沒有命中的時候,瀏覽器會發送一個請求到服務器,服務器根據 header 中的部分信息來判斷是否命中協商緩存。
協商緩存標誌分為Last-Modify/If-Modify-SinceETag/If-None-Match

Last-Modify/If-Modify-Since

瀏覽器第一次請求一個資源的時候,服務器返回的 header 中會加上 Last-Modify,Last-modify 是一個時間標識該資源的最後修改時間。

當瀏覽器再次請求該資源時,request 的請求頭中會包含 If-Modify-Since,該值為緩存之前返回的 Last-Modify。服務器收到 If-Modify-Since 後,根據資源的最後修改時間判斷是否命中緩存。

如果命中緩存,則返回 304,並且不會返回資源內容,並且不會返回 Last-Modify。

缺點:

短時間內資源發生了改變,Last-Modified 並不會發生變化。

週期性變化。如果這個資源在一個週期內修改回原來的樣子了,我們認為是可以使用緩存的,但是 Last-Modified 可不這樣認為,因此便有了 ETag。

ETag/If-None-Match

與 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一個校驗碼。ETag 可以保證每一個資源是唯一的,資源變化都會導致 ETag 變化。服務器根據瀏覽器上送的 If-None-Match 值來判斷是否命中緩存。

與 Last-Modified 不一樣的是,當服務器返回 304 Not Modified 的響應時,由於 ETag 重新生成過,response header 中還會把這個 ETag 返回,即使這個 ETag 跟之前的沒有變化。

Last-Modified 與 ETag 是可以一起使用的,服務器會優先驗證 ETag,一致的情況下,才會繼續比對 Last-Modified,最後才決定是否返回 304。

部分內容引用自《實踐這一次,徹底搞懂瀏覽器緩存機制》:https://segmentfault.com/a/11...
user avatar 1023 頭像 ivyzhang 頭像 ziyeliufeng 頭像 zhangxishuo 頭像 suporka 頭像 tingzhong666 頭像 201926 頭像 niumingxin 頭像 qianduanlangzi_5881b7a7d77f0 頭像 joytime 頭像 mrqueue 頭像 lidalei 頭像
21 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.