瀏覽器緩存做爲性能優化的重要一環,對於前端而言,重要性不言而喻。之前老是隻知其一;不知其二的,因此此次好好整理總結了一下。
首先咱們來整體感知一下它的匹配流程,以下:css
強緩存:不會向服務器發送請求,直接從緩存中讀取資源。前端
強制緩存就是向瀏覽器緩存查找該請求結果,並根據該結果的緩存規則來決定是否使用該緩存結果的過程,強制緩存的狀況主要有三種(暫不分析協商緩存過程),以下:nginx
那麼強制緩存的緩存規則是什麼?
當瀏覽器向服務器發起請求時,服務器會將緩存規則放入HTTP響應報文的HTTP頭中和請求結果一塊兒返回給瀏覽器,控制強制緩存的字段分別是Expires
和Cache-Control
,其中Cache-Control
優先級比Expires
高。git
緩存過時時間,用來指定資源到期的時間,是服務器端的具體的時間點。也就是說,Expires=max-age + 請求時間
,須要和Last-modified
結合使用。Expires
是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。github
Expires 是 HTTP/1 的產物,受限於本地時間,若是修改了本地時間,可能會形成緩存失效。
在HTTP/1.1中,Cache-Control是最重要的規則,主要用於控制網頁緩存,主要取值爲:瀏覽器
Cache-Control
的默認取值須要注意的是,no-cache
這個名字有一點誤導。設置了no-cache
以後,並非說瀏覽器就再也不緩存數據,只是瀏覽器在使用緩存數據時,須要先確認一下數據是否還跟服務器保持一致,也就是協商緩存。而no-store
才表示不會被緩存,即不使用強制緩存,也不使用協商緩存
強緩存須要服務端設置expires
和cache-control
。nginx
代碼參考,設置了一年的緩存時間:緩存
location ~ .*\.(ico|svg|ttf|eot|woff)(.*) { proxy_cache pnc; proxy_cache_valid 200 304 1y; proxy_cache_valid any 1m; proxy_cache_lock on; proxy_cache_lock_timeout 5s; proxy_cache_use_stale updating error timeout invalid_header http_500 http_502; expires 1y; }
瀏覽器的緩存存放在哪裏,如何在瀏覽器中判斷強制緩存是否生效?這就是下面咱們要講到的from disk cache
和from memory cache
。性能優化
細心地同窗在開發的時候應該注意到了Chrome的網絡請求的Size會出現三種狀況from disk cache(磁盤緩存)
、from memory cache(內存緩存)
、以及資源大小數值。服務器
狀態 | 類型 | 說明 |
---|---|---|
200 | form memory cache | 不請求網絡資源,資源在內存當中,通常腳本、字體、圖片會存在內存當中 |
200 | form disk ceche | 不請求網絡資源,在磁盤當中,通常非腳本會存在內存當中,如css等 |
200 | 資源大小數值 | 從服務器下載最新資源 |
304 | 報文大小 | 請求服務端發現資源沒有更新,使用本地資源 |
瀏覽器讀取緩存的順序爲memory –> disk。
以訪問https://github.com/xiangxingchen/blog
爲例
咱們第一次訪問時https://github.com/xiangxingchen/blog
關閉標籤頁,再此打開https://github.com/xiangxingchen/blog
時
F5刷新時
網絡
簡單的對比一下
協商緩存就是強制緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程,主要有如下兩種狀況:
response header
中返回請求的資源上次更新時間,就是last-modified
,瀏覽器會緩存下這個時間。request header
中帶上if-modified-since
:[保存的last-modified的值]
。根據瀏覽器發送的修改時間和服務端的修改時間進行比對,一致的話表明資源沒有改變,服務端返回正文爲空的響應,讓瀏覽器中緩存中讀取資源,這就大大減少了請求的消耗。因爲last-modified依賴的是保存的絕對時間,仍是會出現偏差的狀況:
etag
是http
協議提供的若干機制中的一種Web
緩存驗證機制,而且容許客戶端進行緩存協商。生成etag經常使用的方法包括對資源內容使用抗碰撞散列函數,使用最近修改的時間戳的哈希值,甚至只是一個版本號。 和last-modified
同樣.
etag
的值,而後再下一次請求在request header
中帶上if-none-match
:[保存的etag的值]
。etag
的值和服務端從新生成的etag
的值進行比對,若是一致表明資源沒有改變,服務端返回正文爲空的響應,告訴瀏覽器從緩存中讀取資源。etag可以解決last-modified的一些缺點,可是etag每次服務端生成都須要進行讀寫操做,而last-modified只須要讀取操做,從這方面來看,etag的消耗是更大的。
兩者對比
Etag
要優於Last-Modified
。Etag
。Etag
要遜於Last-Modified
disk cache
中是否有匹配。若有則使用;如沒有則發送網絡請求。memory cache
是可用的,會被優先使用(若是匹配的話)。其次纔是 disk cache
。Cache-control:no-cache
(爲了兼容,還帶了 Pragma:no-cache
),服務器直接返回 200 和最新內容。
若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是喜歡或者有所啓發,歡迎 star對做者也是一種鼓勵。