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

緩存策略 圖片來源:IMWeb前端
涉及緩存機制的HTTP-header
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刷新,跳過強緩存和協商緩存,直接從服務器拉取資源
寫在最後
- 如果你覺得這篇文章對你有益,煩請點贊以及分享給更多需要的人!