http緩存策略

瀏覽器一般緩存圖片、CSS、JS等靜態文件,因爲這些文件的更新頻率相對來說比較低,合理利用瀏覽器的緩存對網站的性能提升有很大幫助。HTTP緩存分爲兩部分,分別是本地緩存和緩存協商,當本地緩存不生效時會啓用緩存協商。HTTP緩存主要由HTTP協議的頭(Header)信息來制定。

NJzEvuy.png!web

本地緩存

本地緩存是指瀏覽器請求資源時命中了瀏覽器本地的緩存資源,瀏覽器並不會發送真正的請求給服務器了。它的執行過程是:

  1. 第一次瀏覽器發送請求給服務器時,此時瀏覽器還沒有本地緩存副本,服務器返回資源給瀏覽器,響應碼是200 OK,瀏覽器收到資源後,把資源和對應的響應頭一起緩存下來。

  2. 第二次瀏覽器準備發送請求給服務器時候,瀏覽器會先檢查上一次服務端返回的響應頭信息中的Cache-Control,它的值是一個相對值,單位爲秒,表示資源在客戶端緩存的最大有效期,過期時間爲第一次請求的時間減去Cache-Control的值,過期時間跟當前的請求時間比較,如果本地緩存資源沒過期,那麼命中緩存,不再請求服務器。

  3. 如果沒有命中,瀏覽器就會把請求發送給服務器,進入緩存協商階段。

em6Vn2.png!web

與本地緩存相關的頭有:Cache-Control、Expires,Cache-Control有多個可選值代表不同的意義,而Expires就是一個日期格式的絕對值。

Cache-Control

Cache-Control是HTPP緩存策略中最重要的頭,它是HTTP/1.1中出現的,它由如下幾個值

  • no-cache:不使用本地緩存。需要使用緩存協商,先與服務器確認返回的響應是否被更改,如果之前的響應中存在ETag,那麼請求的時候會與服務端驗證,如果資源未被更改,則可以避免重新下載。

  • no-store:直接禁止遊覽器緩存數據,每次用戶請求該資源,都會向服務器發送一個請求,每次都會下載完整的資源。

  • public:可以被所有的用戶緩存,包括終端用戶和CDN等中間代理服務器。

  • private:只能被終端用戶的瀏覽器緩存,不允許CDN等中繼緩存服務器對其緩存。

  • max-age:從當前請求開始,允許獲取的響應被重用的最長時間(秒)。

例如:

Cache-Control:public, max-age=1000

表示資源可以被所有用戶以及代理服務器緩存,最長時間爲1000秒。

Expires

Expires是HTTP/1.0出現的頭信息,同樣是用於決定本地緩存策略的頭,它是一個絕對時間,時間格式是如 Mon, 10 Jun 2015 21:31:12 GMT ,只要發送請求時間是在Expires之前,那麼本地緩存始終有效,否則就會去服務器發送請求獲取新的資源。如果同時出現Cache-Control:max-age和Expires,那麼max-age優先級更高。他們可以這樣組合使用:

Cache-Control:publicExpires: Mon, 10 Jun 2015 21:31:12 GMT

緩存協商

當第一次請求時服務器返回的響應頭中沒有Cache-Control和Expires或者Cache-Control和Expires過期抑或它的屬性設置爲no-cache時,那麼瀏覽器第二次請求時就會與服務器進行協商,詢問瀏覽器中的緩存資源是不是舊版本,需不需要更新,此時,服務器就會做出判斷,如果緩存和服務端資源的最新版本是一致的,那麼就無需再次下載該資源,服務端直接返回304 Not Modified 狀態碼,如果服務器發現瀏覽器中的緩存已經是舊版本了,那麼服務器就會把最新資源的完整內容返回給瀏覽器,狀態碼就是200 Ok,那麼服務端是根據什麼來判斷瀏覽器的緩存是不是最新的呢?其實是根據HTTP的另外兩組頭信息,分別是: Last-Modified/If-Modified-Since 與 ETag/If-None-Match 。

zIjQjmZ.png!web

Last-Modified與If-Modified-Since

瀏覽器第一次請求資源時,服務器會把資源的最新修改時間Last-Modified:Thu, 29 Dec 2011 18:23:55 GMT放在響應頭中返回給瀏覽器,第二次請求時,瀏覽器就會把上一次服務器返回的修改時間放在請求頭 If-Modified-Since:Thu, 29 Dec 2011 18:23:55 發送給服務器,服務器就會拿這個時間跟服務器上的資源的最新修改時間進行對比,如果兩者相等或者大於服務器上的最新修改時間,那麼表示瀏覽器的緩存是有效的,此時緩存會命中,服務器就不再返回內容給瀏覽器了,同時Last-Modified頭也不會返回,因爲資源沒被修改,返回了也沒什麼意義。如果沒命中緩存則最新修改的資源連同Last-Modified頭一起返回。

第一次請求返回的響應頭:

Cache-Control:max-age=3600Expires:Tue, 26 Jan 2016 08:28:52 GMTLast-Modified:Fri, 15 Jan 2016 12:06:06 GMT

第二次請求的請求頭信息:

If-Modified-Since:Fri, 15 Jan 2016 12:06:06 GMT

這組頭信息是基於資源的修改時間來判斷資源有沒有更新,另一種方式就是根據資源的內容來判斷,就是接下來要討論的ETag與If-None-Match

ETag與If-None-Match

ETag/If-None-Match與Last-Modified/If-Modified-Since的流程其實是類似的,唯一的區別是它基於資源的內容的摘要信息(比如MD5 hash)來判斷。瀏覽器發送第二次請求時,會把第一次的響應頭信息ETag的值放在If-None-Match的請求頭中發送到服務器,與最新的資源的摘要信息對比,如果相等,取瀏覽器緩存,否則內容有更新,最新的資源連同最新的摘要信息返回。用ETag的好處是如果因爲某種原因到時資源的修改時間沒改變,那麼用ETag就能區分資源是不是有被更新。原文

第一次請求返回的響應頭:

Cache-Control:public, max-age=31536000ETag: "15f0fff99ed5aae4edffdd6496d7131f"

第二次請求的請求頭信息:

If-None-Match: "15f0fff99ed5aae4edffdd6496d7131f"


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章