寫在前面的話
緩存是前端面試中的必問題目html
緩存對於web開發有重要做用,尤爲是大負荷web系統開發中前端
想了解更多關於性能優化的知識,請移步[三分鐘小文]前端性能優化-HTML、CSS、JS部分、[三分鐘小文]前端性能優化-頁面加載速度優化、[三分鐘小文]前端性能優化-網絡傳輸層優化git
文章建議閱讀時間:5分鐘github
本篇文章同時收錄【前端知識點】中,連接直達web
閱讀本文您將收穫
- 緩存的相關概念
- 緩存的做用
- 緩存機制
- 緩存策略詳解
緩存的概念知識
- 緩存的分類:服務器緩存(代理服務器緩存、CDN 緩存),第三方緩存,瀏覽器緩存等。
- 緩存的相關術語:
- 緩存命中率:從緩存中獲得數據的請求數與全部請求數的比率。理想狀態是越高越好。
- 過時內容:超過設置的有效時間,被標記爲 '陳舊' 的內容。一般過時內容不能用於回覆客戶端的請求,必須從新向源服務器請求新的內容或者驗證緩存的內容是否仍然可用。
- 驗證:驗證緩存中的過時內容是否仍然有效,驗證經過的話刷新過時時間或策略。
- 失效:失效就是把內容從緩存中移除。當內容發生改變時就必須移除失效的內容。
- 另: 瀏覽器緩存是代價最小的,由於瀏覽器緩存依賴的是客戶端,而幾乎不耗費服務器端的資源(極端狀況下至關於純靜態頁面)。
緩存的做用
- 減小網絡帶寬消耗
- 下降服務器壓力
- 減小網絡延遲,加快頁面打開速度
緩存機制
- 強緩存優先於協商緩存,強緩存生效則使用強緩存,若強緩存失敗,則進行協商緩存
- 協商緩存由服務器決定是否使用緩存,若協商緩存失效,那麼表明該請求的緩存失效,從新獲取請求結果,再存入瀏覽器緩存中;生效則返回304,繼續使用緩存

緩存策略 圖片來源:IMWeb前端
Expires(過時時間)(強緩存機制)
- 值:是一個GMT時間格式的絕對時間,
Expires
的日期時間必須是格林威治時間(GMT),而不是本地時間。舉例:Expires: Fri, 30 Oct 1998 14:19:41
- 做用:告訴緩存器相關副本在多長時間內是新鮮的。過了這個時間,緩存器就會向源服務器發送請求,檢查文檔是否被修改。
- 兼容性:幾乎全部的緩存服務器都支持Expires(過時時間)屬性
- 規則:基於客戶最後查看副本的時間(最後訪問時間)或者根據服務器上文檔最後被修改的時間
- 應用:
- 對於設置靜態圖片文件(例如導航欄和圖片按鈕)緩存特別有用;由於這些圖片修改不多,你能夠給它們設置一個特別長的過時時間,這會使你的網站對用戶變得相應很是快
- 對於控制有規律改變的網頁也頗有用,例如:你天天早上6點更新新聞頁,你能夠設置副本的過時時間也是這個時間,這樣緩存服務器就知道何時去取一個更新版本,而沒必要讓用戶去按瀏覽器的"刷新"按鈕。
- 過時時間頭信息屬性值只能是HTTP格式的日期時間,其餘的都會被解析成當前時間"以前",副本會過時
- 侷限性:雖然過時時間屬性很是有用,可是它仍是有些侷限,
- 首先:是牽扯到了日期,這樣Web服務器的時間和緩存服務器的時間必須是同步的,若是有些不一樣步,要麼是應該緩存的內容提早過時了,要麼是過時結果沒及時更新。
- 若是你設置的過時時間是一個固定的時間,若是你返回內容的時候又沒有連帶更新下次過時的時間,那麼以後全部訪問請求都會被髮送給源Web服務器,反而增長了負載和響應時間
Cache-Control(緩存控制)(強緩存機制)
- 值:
max-age=[秒]
— 執行緩存被認爲是最新的最長時間。
- 相對時間,不是絕對時間
- 單位是秒:從請求時間 開始到過時時間之間的秒數。
- 做用:讓網站的發佈者能夠更全面的控制他們的內容,並定位過時時間的限制。是http 1.1中爲了彌補
Expires
缺陷新加入的。
- 相關控制字段:
s-maxage=[秒]
— 相似於max-age屬性,除了他應用於共享(如:代理服務器)緩存
public
— 標記認證內容也能夠被緩存,通常來講: 通過HTTP認證才能訪問的內容,輸出是自動不能夠緩存的;
no-cache
— 強制每次請求直接發送給源服務器,而不通過本地緩存版本的校驗。這對於須要確認認證應用頗有用(能夠和public結合使用),或者嚴格要求使用最新數據 的應用(不惜犧牲使用緩存的全部好處);
no-store
— 強制緩存在任何狀況下都不要保留任何副本
must-revalidate
— 告訴緩存必須遵循全部你給予副本的新鮮度的
proxy-revalidate
— 和 must-revalidate
相似,除了他只對緩存代理服務器起做用
Last-Modified/If-Modified-Since (協商緩存機制)
- 一般服務器知道你所請求的數據的最後修改時間,而且 HTTP 爲服務器提供了一種將最近修改數據連同你請求的數據一同發送的方法。
- 若是你第二次 (或第三次,或第四次) 請求相同的數據,告訴服務器上一次得到的最後修改日期:在請求中發送一個
If-Modified-Since
頭信息,它包含了上一次從服務器連同數據所得到的日期。
- 若是數據從那時起沒有改變,服務器將返回一個特殊的 HTTP 狀態代碼 304,這意味着 「從上一次請求後這個數據沒有改變」。
- 當服務器發送狀態編碼 304 時,再也不從新發送數據。因此當數據沒有更新時,你不須要一次又一次地下載相同的數據
- 兼容性 :全部現代的瀏覽器都支持 (
last-modified
) 的數據檢查。
ETag/If-None-Match (協商緩存機制)
- 做用: 沒有變化時不從新下載數據
- 工做方式 :
Etag
是上一次加載資源時,服務器返回的 response header
,是對該資源的一種惟一標識,只要資源有變化,Etag
就會從新生成
- 瀏覽器在下一次加載資源向服務器發送請求時,會將上一次返回的
Etag
值放到 request header
裏的 If-None-Match
裏,服務器比較客戶端傳來的 If-None-Match
跟本身服務器上該資源的 ETag
是否一致
- 若是服務器發現
ETag
匹配不上,那麼直接以常規 GET 200
回包形式將新的資源(固然也包括了新的 ETag
)發給客戶端;若是 ETag
是一致的,則直接返回304知會客戶端直接使用本地緩存便可。
幾種緩存策略的對比
兩種強緩存機制對比 Expires
VS Cache-Control
- 差異不大,區別就是
Expires
是 HTTP1.0
的產物,而 Cache-Control
是 HTTP1.1
的產物
- 優先級上,二者同時存在的話,
Cache-Control
優先級高於 Expires
,Expires
更像是一種備選方案,在某些不支持 Cache-Control
的環境中發揮做用
- 兩者共同的弊端 就是這種強緩存的機制僅僅關心緩存是否超出或者超過某個過時時間,並不關心服務器端的資源是否已經更新,因此單純使用這兩種緩存策略會致使客戶端拿到的資源不是最新的
兩種協商緩存機制對比 Last-Modified/If-Modified-Since
VS ETag/If-None-Match
- 精度上,
ETag
要明顯優於前者,Last-Modified/If-Modified-Since
策略的時間單位爲秒,這就意味着在秒級的請求上,作不到真正的及時更新,可是 ETag
每次請求都會對其進行改變從而確保精度,而且在使用負載均衡的服務器上,各個服務器生成的 Last-Modified
也有可能不相同
- 性能上,
ETag
要遜於 Last-Modified/If-Modified-Since
策略,畢竟 Last-Modified/If-Modified-Since
策略只是記錄時間,而 ETag
須要進行一步hash運算
- 優先級上,服務器會優先考慮
ETag
用戶行爲對緩存策略的影響
並非全部的操做都會啓用正常的緩存機制,在某些用戶行爲下,緩存機制是能夠正常跳過的面試
- 地址欄訪問,連接跳轉是正經常使用戶行爲,將會觸發瀏覽器緩存機制
- F5刷新,瀏覽器會設置
max-age=0
,跳過強緩存判斷,會進行協商緩存判斷
- ctrl+F5刷新,跳過強緩存和協商緩存,直接從服務器拉取資源
寫在最後
- 若是你以爲這篇文章對你有益,煩請點贊以及分享給更多須要的人!
快到碗裏來!百度校招還有HC!甩簡從來!
極速直接內推【字節跳動】&【百度】&【猿輔導】&【京東】
歡迎關注微信公衆號【全棧道路】,獲取更多科技相關知識及免費書籍。


更多好文
Vue3.0 響應式數據原理:ES6 Proxy瀏覽器
幾行代碼教你解決微信生成海報及二維碼緩存
冷門的HTML - tabindex 的做用性能優化
[萬字長文]百度和好將來面試經含答案服務器
[前端面試]前端緩存問題看這篇,讓面試官愛上你
記一次慘痛的Vue-cli + VueX + SSR經歷
[三分鐘小文]前端性能優化-HTML、CSS、JS部分
[三分鐘小文]前端性能優化-頁面加載速度優化
[三分鐘小文]前端性能優化-網絡傳輸層優化