博客 / 詳情

返回

瀏覽器緩存機制

瀏覽器緩存機制

前言

緩存是性能優化中簡單高效的優化方式,可以縮短網頁請求資源的距離,減少延遲,並且由於緩存文件可以重複利用,還可以減少帶寬,降低網絡負荷,可以極大的提升用户體驗。

為什麼可以優化性能呢?若瀏覽器已經將資源緩存下來,那麼再次需要資源時,可以直接使用緩存而不發送請求或發起請求後但瀏覽器緩存與服務器存儲內容一樣則不必再將數據傳回。

image

緩存位置

一共有4個緩存位置,存在優先級,當依次查找都未命中時,才會去請求網絡。

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

Service Worker

Service Worker是運行在瀏覽器背後的獨立線程,一般用來實現緩存功能。要使用Service Worker的話,要求傳輸協議必須為HTTPS。Service Worker 的緩存與瀏覽器其他內建的緩存機制不同,它可以讓我們自由控制緩存哪些文件、如何匹配緩存、如何讀取緩存,並且緩存是持續性的

Service Worker 實現緩存功能一般分為三個步驟:首先需要先註冊 Service Worker,然後監聽到 install 事件以後就可以緩存需要的文件,那麼在下次用户訪問的時候就可以通過攔截請求的方式查詢是否存在緩存,存在緩存的話就可以直接讀取緩存文件,否則就去請求數據。

Memory Cache

Memory Cache是內存中的緩存,主要包含的是當前頁面中已經抓取到的資源。例如頁面上已下載的樣式、腳本、圖片等。讀取速度快,但容量小且持續時間短,一旦關閉Tab頁面,內存中的緩存即被釋放。

Disk Cache

Disk Cache即存儲在硬盤中的緩存,讀取速度慢,但容量的,存儲時效長。

Memory Cache Disk Cache
相同點 只能存儲一些派生類資源文件 只能存儲一些派生類資源文件
不同點 退出進程時數據會被清除 退出進程時數據不會被清除
存儲資源 一般腳本、字體、圖片會存在內存當中 一般非腳本會存在內存當中,如css等

Push Cache

Push Cache即推送緩存,是HTTP/2中的內容,當以上3種緩存方法沒有命中時才會被使用。它只會在會話(Session)中存在,一旦會話結束就被釋放,並且緩存時間短暫。

緩存機制

對於瀏覽器的緩存來講,緩存規則是在HTTP協議頭部和HTML頁面的Meta標籤中定義的。分別從新鮮度和校驗值兩個維度來規定瀏覽器是否可以直接使用緩存中的副本,還是需要去源服務器獲取新版本。

過期機制

指的是緩存副本的有效期。一個緩存的副本必須滿足以下任一條件,瀏覽器會認為它是有效的,足夠新的,可以使用的:

  1. 含有完整的過期時間控制頭信息(HTTP協議報頭),並且仍在有效期內
  2. 瀏覽器已經使用過這個緩存副本,並且會在一個會話中已經檢查過新鮮度(即服務器上的資源是否發生改變)

校驗值

服務器返回資源的時候有時在控制頭信息帶上這個資源的實體標籤Etag(Entity Tag),可以用來作為瀏覽器再次請求過程中的校驗標識,如果發現不匹配,説明資源已經被修改或過期,瀏覽器需要重新獲取資源內容。

緩存過程分析

瀏覽器緩存在已經將資源緩存下來的條件下才成立。在瀏覽器第一次請求某資源時,由於其從未緩存過,所以是另一套緩存流程。

瀏覽器每次發送請求,都會先在瀏覽器緩存中查找該請求的結果和緩存標識。

瀏覽器每次拿到返回的請求結果都會將該結果和緩存標識存入瀏覽器緩存中。

img

我們根據是否需要向服務器重新發起HTTP請求將緩存過程分為兩種方式:強緩存和協商緩存。

強緩存 協商緩存
定義 用户發送請求,直接從客户端緩存中獲取,不發送請求到服務器,不與服務器發生交互行為 用户發送請求,發送到服務端之後,由服務器判斷是否從緩存中獲取資源
共同 客户端最後獲取的數據都是從客户端緩存中獲得 客户端最後獲取的數據都是從客户端緩存中獲得
區別 不與服務器發生交互 需要與服務器發生交互

強緩存

強緩存不會向服務器發送請求,直接從緩存中讀取資源。可以通過設置兩種HTTP Header實現:Expires和Cache-Control。

Expires

Expires為HTTP/1的產物,意思為緩存過期時間,用來指定資源到期時間,是服務器端的具體的時間點。也就是説,Expires=max-age + 請求時間,需要和 Last-modified 結合使用。Expires 是 Web 服務器響應消息頭字段,在響應 http 請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數據,而無需再次請求。

Cache-Control

HTTP/1.1新增,主要用於控制網頁緩存。可以在請求頭或響應頭中設置,並且可以組合使用多種指令。

imgimg

對比

所處HTTP版本不同,Expires是過時的產物,當兩者同時存在時,Cache-Control優先級高於Expires。

強緩存不關心服務器端的文件是否更新,這可能會導致加載文件不是服務端最新內容,此時就需要協商緩存策略。

協商緩存

協商緩存就是在強制緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程,主要情況分為協商緩存生效和協商緩存失效。

  • 協商緩存生效,返回304和Not Modified,表示服務端內容未更新,可以直接使用瀏覽器中緩存的內容

    img

  • 協商緩存失敗,返回200和請求結果,表示服務端內容更新,重新返回請求結果

    img

    協商緩存可以通過設置兩種HTTP Header實現:Last-Modified和ETag。

Last-Modified和If-Modified-Since

瀏覽器在第一次訪問資源時,服務器返回資源的同時,在response header中添加 Last-Modified的header,值是這個資源在服務器上的最後修改時間,瀏覽器接收後緩存文件和header。

瀏覽器下一次請求這個資源,瀏覽器檢測到有 Last-Modified這個header,於是添加If-Modified-Since這個header,值就是Last-Modified中的值;服務器再次收到這個資源請求,會根據 If-Modified-Since 中的值與服務器中這個資源的最後修改時間對比,如果沒有變化,返回304和空的響應體,直接從緩存讀取,如果If-Modified-Since的時間小於服務器中這個資源的最後修改時間,説明文件有更新,於是返回新的資源文件和200。

img

弊端:

  • 如果本地打開緩存文件,即使沒有對文件進行修改,但還是會造成 Last-Modified 被修改,服務端不能命中緩存導致發送相同的資源
  • 因為 Last-Modified 只能以秒計時,如果在不可感知的時間內修改完成文件,那麼服務端會認為資源還是命中了,不會返回正確的資源
ETag和If-None-Match

ETag是服務器響應請求時,返回當前資源文件的一個唯一標識(由服務器生成),只要資源變化,ETag就會重新生成。瀏覽器在下一次加載資源向服務器發送請求時,會將上一次返回的Etag值放到request header裏的If-None-Match裏,服務器只需要比較客户端傳來的If-None-Match跟自己服務器上該資源的ETag是否一致,就能很好地判斷資源相對客户端而言是否被修改過了。如果服務器發現ETag匹配不上,那麼直接以常規GET 200回包形式將新的資源(當然也包括了新的ETag)發給客户端;如果ETag是一致的,則直接返回304知會客户端直接使用本地緩存即可。

img

對比
  • 在精確度上,ETag優於Last-Modified
  • 在性能上,ETag差於Last-Modified,因為ETag需要服務器通過算法計算出一個hash值
  • 在優先級上,服務器校驗優先考慮ETag

流程

瀏覽器請求到展示資源的整個過程

圖片61.png

參考

​ 深入理解瀏覽器的緩存機制

​ 淺談 Web 緩存

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.