浏览器缓存机制的研究分享
源寶導讀:互聯(lián)網(wǎng)Web應用大行其道的今天,瀏覽器已經(jīng)成為Web應用運行的重要平臺。而Web應用對瀏覽器緩存機制的高效利用,可以大幅提升應用性能和用戶體驗。本文將對瀏覽器緩存機制進行系統(tǒng)化的梳理,分享我們的經(jīng)驗。
一、背景
? ? 計算機讀取數(shù)據(jù)的速度逐步遞減:緩存>內(nèi)存>硬盤, 為了提高數(shù)據(jù)處理性能,其中一個策略就是對緩存的高效利用。類似的,利用瀏覽器緩存是Web應用性能優(yōu)化的重要手段之一。優(yōu)先的緩存策略可以縮短網(wǎng)頁請求資源的距離,減少延遲,并且可以緩存文件進行復用,還可以減少帶寬,降低網(wǎng)絡負荷。
? ? 對于一個數(shù)據(jù)請求來說,可以分為“發(fā)起請求”、“后端處理”、“瀏覽器響應”3個階段,對緩存的高效利用,可以大幅提升前2步的性能。
二、對瀏覽器緩存機制的研究
2.1、緩存類型
Memory Cache
memory cache 是內(nèi)存中的緩存,主要包含當前頁面中已經(jīng)抓取到的資源。Disk Cache
disk cache 是硬盤中的緩存。
? ? 通常瀏覽器緩存分為2種:強緩存和協(xié)商緩存,并且都是通過設置HTTP Header實現(xiàn)的。
2.2、緩存過程
? ? 瀏覽器每次發(fā)起請求,都會先在瀏覽器緩存中查找請求的結果和標識。瀏覽器每次拿到返回的請求都會將該結果和緩存標識存入緩存中。
先檢查內(nèi)存,如果有,直接返回。
如果內(nèi)存沒有,則去硬盤獲取,如果有直接返回。
如果硬盤也沒有,那么就進行網(wǎng)絡請求。
加載到的資源緩存到硬盤和內(nèi)存。
2.3、強緩存
? ? 強緩存:不會向服務器發(fā)生請求,直接從緩存中讀取資源。在 chrome 控制臺可以看到該請求返回 200 的狀態(tài)碼,并且 size 顯示 from disk cache 或 from memory cache。
? ? 強緩存可以通過設置HTTP Header 實現(xiàn):expires 和 Cache-Control。
expires
緩存過期時間,用來指定資源到期時間,是服務器的具體的時間點。expires=max-age + 請求時間,需要和 last-modified 結合使用。expires 是 HTTP/1 的產(chǎn)物,受限于本地時間,修改本地時間,可能會導致緩存失效。cache-control
cache-control 可以在請求頭或響應頭中設置,可以組合使用多種指令。public:所有內(nèi)容都會被緩存。
private: 所有內(nèi)容只有客戶端可以緩存。
no-cache: 不是說瀏覽器不使用緩存,而是先確認下數(shù)據(jù)和服務器是否一致。也就是使用 etag 或者 last-modified 控制緩存。
no-store:所有內(nèi)容都不緩存,不使用強緩存也不使用協(xié)商緩存。
max-age: 表示緩存內(nèi)容在多久后失效。
s-maxage: 同 max-age,但是只在代理服務器生效(比如 cdn)。
max-stale: 能容忍的最大過期時間。
max-fresh: 能容忍的最小新鮮度。
expires 是 HTTP 1.0 的產(chǎn)物,cache-control 是 HTTP 1.1 的產(chǎn)物,兩者同時存在時,cache-control 優(yōu)先級更高。從下圖中可以發(fā)現(xiàn)強緩存瀏覽器加載速度超快,沒有與服務器發(fā)生交互。
2.4、協(xié)商緩存
? ? 強緩存判斷緩存是否超出某個時間或者范圍,但是不關心服務器是否已經(jīng)更新內(nèi)容。為了獲取服務器更新,就需要使用協(xié)商緩存。
? ? 協(xié)商緩存就是強制緩存失效后,瀏覽器攜帶緩存標識向服務器發(fā)起請求,由服務器決定是否使用緩存。主要有 2 種情況:
協(xié)商緩存生效,返回304和 no modified。
協(xié)商緩存失效,返回200和請求結果。
? ? 協(xié)商緩存通過 2 中 HTTP Heeader 設置:last-modified 和 etag。
2.4.1、last-modified和if-modified-since
? ? 瀏覽器在第一次訪問資源時,服務器返回資源的同時,在 響應頭添加 last-modified,值是這個資源在服務器上的最后修改時間。
? ? 瀏覽器下一次請求,服務器檢測到 last-modified 的值,再添加個 if-modified-since 值是 last-modified 的值。服務器再次收到請求,會根據(jù) last-modified-since 的值與服務器中這個資源的最后修改時間對比。相同 304,如果 if-modified-since 的值比服務器上資源最后修改時間小,返回新的資源和 200。
? ? last-modified 存在的弊端:
如果在本地打開緩存文件,即使沒有改內(nèi)容,last-modified 也會被修改,服務器就不能命中緩存。
last-modified 只能以秒計時,如果在不可感知的時間內(nèi)修改,服務器還是會認為命中緩存了。
有的服務器文件沒有修改,可能也會更新修改時間。
2.4.2、etag和if-none-match
? ? etag是服務器響應請求時,返回當前資源文件的一個唯一標識(由服務器生成,通常是文件的內(nèi)容md5加上修改時間算法計算得出),只要資源有變化,etag 就會重新生成。
? ? 瀏覽器下一次請求時,只需要把上一次 etag 的值寫到 if-none-match 中,服務器再比較 if-none-match 和當前資源的 etag 是否一致。
? ? 從下圖中可知,協(xié)商緩存即使沒有失效,也要請求一次服務器。
2.5、對比
? ? 精度上,etag優(yōu)于last-modified。Last-Modified的時間單位是秒,如果某個文件在1秒內(nèi)改變了多次,那么他們的Last-Modified其實并沒有體現(xiàn)出來修改,但是Etag每次都會改變確保了精度;如果是負載均衡的服務器,各個服務器生成的Last-Modified也有可能不一致。
在性能上,Etag肯定要遜于Last-Modified,畢竟Last-Modified只需要記錄時間,而Etag需要服務器通過算法來計算出一個hash值。
在優(yōu)先級上,服務器校驗優(yōu)先考慮Etag。
2.6、小結
? ? 強緩存優(yōu)先于協(xié)商緩存,若強緩存生效則直接使用緩存,若不生效使用協(xié)商緩存(last-modified/if-modified-since 和 etag/if-none-match)。協(xié)商緩存由服務器決定是否使用緩存。使用緩存返回 304,不使用 返回 200 和 新的資源。用一張圖片總結:
三、應用
3.1、頻繁變動的資源
cache-control: no-cache
通過設置 no-cache 使瀏覽器每次都請求服務器,然后配合使用 etag 或者 last-modified 協(xié)商緩存。
3.2、不常變化的緩存
cache-control: max-age=60480000
? ? 通過設置一個很大的過期時間,瀏覽器就會使用強緩存。而為了解決更新的問題,就需要在文件名(或者路徑)中添加 hash, 版本號等動態(tài)字符,之后更改動態(tài)字符,從而達到更改引用 URL 的目的,讓之前的強制緩存失效 (其實并未立即失效,只是不再使用了而已)。
3.3、SPA頁面
? ? 現(xiàn)在前端三大框架項目通過打包工具打包出來的資源名通常都是資源的md5值計算出來的hash,如果資源不變hash都不會變,可以讓我們有效的利用緩存。但是通常我們的靜態(tài)資源都是通過放在nginx下,而一般我們的nginx項目對靜態(tài)資源的緩存配置緩存了html頁面的靜態(tài)資源,大概配置如下:
location ~\.(css|js|png|jpeg|jpg|wepg|mp3|mp4|ogg|html)$ {expires 7d; }? ? 這樣會導致如果我們更改了文件內(nèi)容,導致hash變化,但是由于html還是取得緩存,這樣我們在發(fā)版的時候,緩存還未失效的用戶可能訪問的還是舊的緩存。導致用戶不用第一時間看見最新版本,或者存在某些引用的資源緩存已經(jīng)失效,但是文件內(nèi)容被更改,此時資源路徑可能在服務器上已經(jīng)不存在,就會導致資源404。
? ? 其實,通常SPA的首頁index.html一般非常小,而其它頁面都是前端路由,只是JS文件,我們針對SPA項目,可以不緩存html資源,針對其它文件則使用強緩存即可,這樣可以提高頁面加載速度。
location ~\.(html)$ {add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate"; } location ~\.(css|js|png|jpeg|jpg|wepg|mp3|mp4|ogg)$ {expires 7d; }------ END ------
作者簡介
李同學:?研發(fā)工程師,目前負責天際-移動平臺的研發(fā)工作。
也許您還想看
記AWSS3在iOS端的一次改造事件
明源云創(chuàng)CI/CD技術演進
微前端架構在容器平臺的應用
AI云店小程序演變之路
天眼探針基于rrweb實現(xiàn)前端異常視頻錄制與回放功能
總結
以上是生活随笔為你收集整理的浏览器缓存机制的研究分享的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OneOfT1,…,Tn清新
- 下一篇: 这套前端可视化框架,让数据栩栩如生!