緩存是性能優化中簡單高效的優化方式,能夠縮短網頁請求資源的距離,減小延遲,而且因爲緩存文件能夠重複利用,還能夠減小帶寬,下降網絡負荷,能夠極大的提高用戶體驗。css
爲何能夠優化性能呢?若瀏覽器已經將資源緩存下來,那麼再次須要資源時,能夠直接使用緩存而不發送請求或發起請求後但瀏覽器緩存與服務器存儲內容同樣則沒必要再將數據傳回。web
一共有4個緩存位置,存在優先級,當依次查找都未命中時,纔會去請求網絡。算法
Service Worker是運行在瀏覽器背後的獨立線程,通常用來實現緩存功能。要使用Service Worker的話,要求傳輸協議必須爲HTTPS。Service Worker 的緩存與瀏覽器其餘內建的緩存機制不一樣,它可讓咱們自由控制緩存哪些文件、如何匹配緩存、如何讀取緩存,而且緩存是持續性的。segmentfault
Service Worker 實現緩存功能通常分爲三個步驟:首先須要先註冊 Service Worker,而後監聽到 install 事件之後就能夠緩存須要的文件,那麼在下次用戶訪問的時候就能夠經過攔截請求的方式查詢是否存在緩存,存在緩存的話就能夠直接讀取緩存文件,不然就去請求數據。瀏覽器
Memory Cache是內存中的緩存,主要包含的是當前頁面中已經抓取到的資源。例如頁面上已下載的樣式、腳本、圖片等。讀取速度快,但容量小且持續時間短,一旦關閉Tab頁面,內存中的緩存即被釋放。緩存
Disk Cache即存儲在硬盤中的緩存,讀取速度慢,但容量的,存儲時效長。性能優化
Memory Cache | Disk Cache | |
---|---|---|
相同點 | 只能存儲一些派生類資源文件 | 只能存儲一些派生類資源文件 |
不一樣點 | 退出進程時數據會被清除 | 退出進程時數據不會被清除 |
存儲資源 | 通常腳本、字體、圖片會存在內存當中 | 通常非腳本會存在內存當中,如css等 |
Push Cache即推送緩存,是HTTP/2中的內容,當以上3種緩存方法沒有命中時纔會被使用。它只會在會話(Session)中存在,一旦會話結束就被釋放,而且緩存時間短暫。服務器
對於瀏覽器的緩存來說,緩存規則是在HTTP協議頭部和HTML頁面的Meta標籤中定義的。分別重新鮮度和校驗值兩個維度來規定瀏覽器是否能夠直接使用緩存中的副本,仍是須要去源服務器獲取新版本。網絡
指的是緩存副本的有效期。一個緩存的副本必須知足如下任一條件,瀏覽器會認爲它是有效的,足夠新的,可使用的:性能
服務器返回資源的時候有時在控制頭信息帶上這個資源的實體標籤Etag(Entity Tag),能夠用來做爲瀏覽器再次請求過程當中的校驗標識,若是發現不匹配,說明資源已經被修改或過時,瀏覽器須要從新獲取資源內容。
瀏覽器緩存在已經將資源緩存下來的條件下才成立。在瀏覽器第一次請求某資源時,因爲其從未緩存過,因此是另外一套緩存流程。
瀏覽器每次發送請求,都會先在瀏覽器緩存中查找該請求的結果和緩存標識。
瀏覽器每次拿到返回的請求結果都會將該結果和緩存標識存入瀏覽器緩存中。
咱們根據是否須要向服務器從新發起HTTP請求將緩存過程分爲兩種方式:強緩存和協商緩存。
強緩存 | 協商緩存 | |
---|---|---|
定義 | 用戶發送請求,直接從客戶端緩存中獲取,不發送請求到服務器,不與服務器發生交互行爲 | 用戶發送請求,發送到服務端以後,由服務器判斷是否從緩存中獲取資源 |
共同 | 客戶端最後獲取的數據都是從客戶端緩存中得到 | 客戶端最後獲取的數據都是從客戶端緩存中得到 |
區別 | 不與服務器發生交互 | 須要與服務器發生交互 |
強緩存不會向服務器發送請求,直接從緩存中讀取資源。能夠經過設置兩種HTTP Header實現:Expires和Cache-Control。
Expires爲HTTP/1的產物,意思爲緩存過時時間,用來指定資源到期時間,是服務器端的具體的時間點。也就是說,Expires=max-age + 請求時間,須要和 Last-modified 結合使用。Expires 是 Web 服務器響應消息頭字段,在響應 http 請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。
HTTP/1.1新增,主要用於控制網頁緩存。能夠在請求頭或響應頭中設置,而且能夠組合使用多種指令。
所處HTTP版本不一樣,Expires是過期的產物,當二者同時存在時,Cache-Control優先級高於Expires。
強緩存不關心服務器端的文件是否更新,這可能會致使加載文件不是服務端最新內容,此時就須要協商緩存策略。
協商緩存就是在強制緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程,主要狀況分爲協商緩存生效和協商緩存失效。
協商緩存能夠經過設置兩種HTTP Header實現:Last-Modified和ETag。
瀏覽器在第一次訪問資源時,服務器返回資源的同時,在response header中添加 Last-Modified的header,值是這個資源在服務器上的最後修改時間,瀏覽器接收後緩存文件和header。
瀏覽器下一次請求這個資源,瀏覽器檢測到有 Last-Modified這個header,因而添加If-Modified-Since這個header,值就是Last-Modified中的值;服務器再次收到這個資源請求,會根據 If-Modified-Since 中的值與服務器中這個資源的最後修改時間對比,若是沒有變化,返回304和空的響應體,直接從緩存讀取,若是If-Modified-Since的時間小於服務器中這個資源的最後修改時間,說明文件有更新,因而返回新的資源文件和200。
弊端:
ETag是服務器響應請求時,返回當前資源文件的一個惟一標識(由服務器生成),只要資源變化,ETag就會從新生成。瀏覽器在下一次加載資源向服務器發送請求時,會將上一次返回的Etag值放到request header裏的If-None-Match裏,服務器只須要比較客戶端傳來的If-None-Match跟本身服務器上該資源的ETag是否一致,就能很好地判斷資源相對客戶端而言是否被修改過了。若是服務器發現ETag匹配不上,那麼直接以常規GET 200回包形式將新的資源(固然也包括了新的ETag)發給客戶端;若是ETag是一致的,則直接返回304知會客戶端直接使用本地緩存便可。
瀏覽器請求到展現資源的整個過程
參考