1. 程式人生 > 其它 >瀏覽器快取機制總結

瀏覽器快取機制總結

瀏覽器快取機制也就是我們常說的HTTP快取機制,根據HTTP報文的快取標識來響應的;

簡單來說,瀏覽器快取其實就是瀏覽器儲存通過HTTP獲取的所有資源,是瀏覽器將網路資源儲存在本地的一種行為;

從快取位置上來劃分的話,分為四種,並且各自有優先順序,當依次查詢快取且都沒有命中的時候,才會去請求網路:

1、Server Worker

2、Memory Cache:

MemoryCache顧名思義,就是將資源快取到記憶體中,等待下次訪問時不需要重新下載資源,而直接從記憶體中獲取。Webkit早已支援memoryCache。
目前Webkit資源分成兩類,一類是主資源,比如HTML頁面,或者下載項,一類是派生資源,比如HTML頁面中內嵌的圖片或者指令碼連結,分別對應程式碼中兩個類:MainResourceLoader和SubresourceLoader。雖然Webkit支援memoryCache,但是也只是針對派生資源,它對應的類為CachedResource,用於儲存原始資料(比如CSS,JS等),以及解碼過的圖片資料。

3、Disk Cache:

DiskCache顧名思義,就是將資源快取到磁碟中,等待下次訪問時不需要重新下載資源,而直接從磁碟中獲取,它的直接操作物件為CurlCacheManager。

4、Push Cache

網路請求

Memory cache | Disk cache 對比:

相同點 只能儲存一些派生類資原始檔 只能儲存一些派生類資原始檔
不同點 退出程序時資料會被清除 退出程序時資料不會被清除
儲存資源 一般指令碼、字型、圖片會存在記憶體當中 一般非指令碼會存在記憶體當中,如css等

像CSS檔案載入一次就可渲染出來,我們不會頻繁讀取它,所以它不適合快取到記憶體中,但是js之類的指令碼卻隨時可能會執行,如果指令碼在磁碟當中,我們在執行指令碼的時候需要從磁碟取到記憶體中來,這樣IO開銷就很大了,有可能導致瀏覽器失去響應;

三級快取原理 (訪問快取優先順序)

  1. 先在記憶體中查詢,如果有,直接載入。
  2. 如果記憶體中不存在,則在硬碟中查詢,如果有直接載入。
  3. 如果硬碟中也沒有,那麼就進行網路請求。
  4. 請求獲取的資源快取到硬碟和記憶體。

瀏覽器快取的優點

1、減少了冗餘的資料傳輸;

2、減少了伺服器的負擔,大大提升了網站的效能;

3、加快了客戶端載入網頁的速度;

瀏覽器快取分為強快取和協商快取兩種:

瀏覽器向伺服器請求資源時,首先判斷是否命中強快取,再判斷是否命中協商快取;

1、強快取:

強快取可以通過設定兩種HTTP Header來實現: Expires 和 Cache-Control

如果快取過期了,就需要發起請求驗證資源是否有更新。

1.1 Expires:

該欄位為http1.0的規範,它的值為GMT格式的時間字串,

比如Expires:Mon,18 Oct 2066 23:59:59 GMT,這個時間代表著這個資源的失效時間,在此時間之前,即命中快取。這種方式有一個明顯的缺點,

由於失效時間是一個絕對時間,所以當伺服器與客戶端時間偏差較大時,或者客戶端手動修改了系統時間時,就會導致快取混亂;

1.2 Cache-Control:

該欄位是http1.1時出現的 header 資訊,主要是利用該欄位的max-age值來進行判斷,它是一個相對時間,例如 Cache-Control:max-age=3600,代表著資源的有效期是 3600 秒。cache-control 除了該欄位外,還有下面幾個比較常用的設定值:

no-cache:需要進行協商快取,傳送請求到伺服器確認是否使用快取。

no-store:禁止使用快取,每一次都要重新請求資料。

public:可以被所有的使用者快取,包括終端使用者和 CDN 等中間代理伺服器。

private:只能被終端使用者的瀏覽器快取,不允許 CDN 等中繼快取伺服器對其快取。

注意:Cache-Control 與 Expires 可以在服務端配置同時啟用,同時啟用的時候 Cache-Control 優先順序高。

2、協商快取

當強快取沒有命中的時候,瀏覽器會發送一個請求到伺服器,伺服器根據 header 中的部分資訊來判斷是否命中快取。如果命中,則返回 304 ,告訴瀏覽器資源未更新,可使用本地的快取。

這裡的 header 中的資訊指的是 Last-Modify/If-Modify-Since 和 ETag/If-None-Match.

2.1 Last-Modify/If-Modify-Since

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

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

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

缺點:

Last-Modified標註的最後修改只能精確到秒級,如果某些檔案在1秒鐘以內,被修改多次的話,它將不能準確標註檔案的修改時間,

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

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

2.2 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。

小結:

當瀏覽器再次訪問一個已經訪問過的資源時,它會這樣做:

1.看看是否命中強快取,如果命中,就直接使用快取了。

2.如果沒有命中強快取,就發請求到伺服器檢查是否命中協商快取。

3.如果命中協商快取,伺服器會返回 304 告訴瀏覽器使用本地快取。

4.否則,返回最新的資源。