求教大神瀏覽器是根據什麼決定from disk cache 與 from memory cache?


謝邀 @溫柔的杜小妹兒 。

對於memory cache的使用,瀏覽器主要是去存儲一些當前獲取到的資源,比如img,第一次載入的時候會去調用requestImage,根據緩存情況來判斷是去add還是update還是從mc里獲取。圖片首次載入會去判斷policy的值而add進mc。再次請求的時候,requestImage的時候判斷policy值存在,就去mc讀取相關緩存。

對於dist的緩存,瀏覽器啟動的時候就會創建一個curl打頭的對象,然後創建一個文件夾,讀取本地緩存文件放進去。然後把文件內容用hashmap表示,請求發出,如果返回200,就去請求遠端數據。如果是304,就會讀取本地文件。如果文件存在,直接從本地獲取。

此外還有更新的一些機制,我就不太了解了。手機打字如果有單詞拼錯見諒,家裡電腦的zx鍵壞了…


首先這個問題我在stackoverflow上關注了好久,就是沒人回答

How chrome browser determine memory cache and disk cache?

上面 姚垚 已經對 memoryCache diskCache 運行機制進行了說明。 就不再補充

其實webkit緩存機制還有一個叫 pageCache 這裡暫不討論

講真這個問題的標準答案,我也不知道,我也非常好奇正確答案, 期待大神的解答。 以下答案就說說我個人使用中的理解。

先來說說 內存緩存的特點 (讀取快) 時效性(進程死,他也死)

第一個現象(以圖片為例):

訪問-&> 200 -&> 退出瀏覽器

再進來-&> 200(from disk cache) -&> 刷新 -&> 200(from memory cache)

總結: 會不會是chrome很聰明的判斷既然已經從disk拿來了, 第二次就內存拿吧 快。(笑哭)

第二個現象(以圖片為例):

只要圖片是base64 我看都是from memroy cache。

總結: 解析渲染圖片這麼費勁的事情,還是做一次然後放到內存吧。 用的時候直接拿

第三個現象(以js css為例):

個人在做靜態測試的發現,大型的js css文件都是直接disk cache

總結: chrome會不會說 我擦 你這麼大 太JB佔地方了。 你就去硬碟里呆著吧。 慢就慢點吧。


因為類似的問題特地找了相關的資料,寫了一篇博文:由memoryCache和diskCache產生的瀏覽器緩存機制的思考

今天在做項目的優化的時候,使用chrome開發者工具的network發現了細節

雖然這兩個看起來都是從緩存中讀取,但還是有一些不一樣的!

webkit資源的分類

webkit的資源分類主要分為兩大類:主資源和派生資

http狀態碼

200 from memory cache

不訪問伺服器,直接讀緩存,從內存中讀取緩存。此時的數據時緩存到內存中的,當kill進程後,也就是瀏覽器關閉以後,數據將不存在。

但是這種方式只能緩存派生資源

200 from disk cache

不訪問伺服器,直接讀緩存,從磁碟中讀取緩存,當kill進程時,數據還是存在。

這種方式也只能緩存派生資源

304 Not Modified

訪問伺服器,發現數據沒有

更新,伺服器返回此狀態碼。然後從緩存中讀取數據。

但是這裡有困惑,怎麼判斷from memory cache還是304

三級緩存原理

1. 先去內存看,如果有,直接載入

2. 如果內存沒有,擇取硬碟獲取,如果有直接載入

3. 如果硬碟也沒有,那麼就進行網路請求

4. 載入到的資源緩存到硬碟和內存

所以我們可以來解釋這個現象

圖片為例:

訪問-&> 200 -&> 退出瀏覽器

再進來-&> 200(from disk cache) -&> 刷新 -&> 200(from memory cache)

http header

max-age

web中的文件被用戶訪問(請求)後的存活時間,是個相對的值,相對Request_time(請求時間)

Expires

Expires指定的時間根據伺服器配置可能有兩種:

1. 文件最後訪問時間

2. 文件絕對修改時間

如果max-age和Expires同時存在,則被Cache-Control的max-age覆蓋

last-modified

WEB 伺服器認為對象的最後修改時間,比如文件的最後修改時間,動態頁面的最後產生時間

ETag

對象(比如URL)的標誌值,就一個對象而言,文件被修改,Etag也會修改

Cache-Control

簡單理解,強緩存

最後結論

見圖片(來源自網路)


伺服器返回請求時添加頭 Response.Headers["Cache-Control"] = "max-age=28800,must-revalidate";

緩存一天,在緩存時間內,瀏覽器不會請求伺服器,直接從本地讀取:from disk cache;

超過了緩存時間,會發送請求攜帶If-None-Match,也就是ETag,到伺服器去檢查,如果頁面沒更新,則返回304,更新了,就返回新的頁面和文件


推薦閱讀:

cdn的緩存數據是如何實現分片的,如何有效的實現各分片的存儲及刪除?
`a = false` 和 `if (a) { a = false; }` 哪個快?
對於平均大小在 10M 至 50M 左右的文件下載服務來說,有沒有什麼成熟的緩存方案呢?
為什麼從Intel Core i系列開始加入L3緩存,而不是使用更大的L2緩存?
新浪微博、Twitter 等 SNS 社交網站如何合理規劃自己的緩存設計?

TAG:前端開發 | 緩存 | HTTP |