簡單來講,瀏覽器緩存就是把一個已經請求過的資源拷貝一份存儲起來,當下次須要該資源時,瀏覽器會根據緩存機制決定直接使用緩存資源仍是再次向服務器發送請求。web
以下圖所示是我在第二次打開某個網頁時的資源請求圖,能夠看出裏面大部分資源是從瀏覽器直接讀取了緩存。瀏覽器
那麼瀏覽器緩存究竟有什麼做用呢?緩存
瀏覽器緩存最主要的做用是減小網絡傳輸的損耗以及下降服務器壓力。服務器
接下來我將經過如下幾個部分來探討瀏覽器緩存機制:網絡
瀏覽器緩存位置分爲四種,其優先級順序以下:工具
當上述四個緩存位置中的緩存都沒有命中時,則會向服務器發起請求。post
Service Worker 是一個註冊在指定源和路徑下的事件驅動 worker。它採用 JavaScript 控制關聯的頁面或者網站,攔截並修改訪問和資源請求,細粒度地緩存資源。網站
咱們能夠經過谷歌開發者工具中的 Application -> Service Workers 查看當前緩存的資源。orm
Memory Cache 即內存中的緩存,其特色是容量小、讀取高效、持續性短,會隨着進程的釋放而釋放。cdn
因此,在內存使用率低、緩存小尺寸資源時,會以 Memory Cache 爲優先,不然使用 Disk Cache。
Disk Cache 即磁盤中的緩存,其特色是容量大、讀取緩慢、持續性長,任何資源都能存儲到磁盤中。
因此,在內存使用率高、緩存大尺寸資源時,會以 Disk Cache 爲優先。
Push Cache 是 HTTP 2.0 中的內容,其緩存時間也很短暫,只在會話(Session)中存在,一旦會話結束就被釋放。
瀏覽器每次在向服務器發起 HTTP 請求得到資源後,可能會根據不一樣狀況(多是代碼控制如 Service Worker、Push Cache,也多是根據 HTTP Header 的緩存標識字段)將資源緩存起來。
瀏覽器緩存策略分爲強制緩存和協商緩存,其是經過設置 HTTP Header 來實現的。
當瀏覽器發起 HTTP 請求時,會依次查找上述緩存位置中是否存在緩存資源並經過緩存標識字段 Expires 或 Cache-Control 來驗證緩存資源是否過時。
Expires 是服務器端在響應請求時用來規定資源的失效時間。
Cache-Control 是服務器端在響應請求時用來規定資源是否須要被瀏覽器緩存以及緩存的有效時間等。
Cache-Control 主要取值以下:
Expires 是 HTTP 1.0 的字段,而 Cache-Control 是 HTTP 1.1 的字段,當 Expires 與 Cache-Control 同時存在時,Cache-Control 的優先級要高於 Expires。
如果命中緩存(即存在緩存資源而且緩存資源未過時),則瀏覽器響應 HTTP Status Code 200,並直接使用緩存資源做爲返回結果,不須要發起 HTTP 請求;如果存在緩存資源但緩存資源已過時,則進入協商緩存。
與協商緩存相關的緩存標識字段是 Last-Modified 和 Etag。
Last-Modified 是服務器端在響應請求時用來講明資源的最後修改時間。與之對應的是 If-Modified-Since 字段,在協商緩存過程當中,瀏覽器發送的 HTTP 請求中 Header 中會帶上 If-Modified-Since 字段,值爲緩存資源 Last-Modified 屬性的值。
當服務器端接收到帶有 If-Modified-Since 的請求時,則會將 If-Modified-Since 的值與被請求資源的最後修改時間作對比。若是相同,說明資源沒有新的修改,則響應 HTTP Status Code 304,瀏覽器會繼續使用緩存資源;若是最後修改時間比較新,則說明資源被修改過,則響應 HTTP Status Code 200,並返回最新的資源。
Etag 是服務器端在響應請求時用來講明資源在服務器端的惟一標識。與之對應的是 If-None-Match 字段,在協商緩存過程當中,瀏覽器發送的 HTTP 請求中 Header 中會帶上 If-None-Match 字段,值爲該緩存資源 Etag 屬性的值。
當服務器端接收到帶有 If-None-Match 的請求時,則會將 If-None-Match 的值與被請求資源的惟一標識作對比。若是相同,說明資源沒有新的修改,則響應 HTTP Status Code 304,瀏覽器會繼續使用緩存資源;若是不一樣,則說明資源被修改過,則響應 HTTP Status Code 200,並返回最新的資源。
Last-Modified 是 HTTP 1.0 的字段,而 Etag 是 HTTP 1.1 的字段,當 Last-Modified 與 Etag 同時存在時,Etag 的優先級要高於 Last-Modified。
Etag 的出現主要是爲了解決 Last-Modified 存在的問題:
下面用一張流程圖來完整說明當瀏覽器發起 HTTP 請求時緩存機制的過程: