瀏覽器緩存策略

瀏覽器展示頁面的耗時很大程度決定於靜態資源的加載速度。那咱們如何提升資源加載的速度呢,方法有不少,但咱們這裏只關心瀏覽器能夠作的事,那就是瀏覽器自己具備的緩存策略。css

那如何控制瀏覽器的緩存策略呢?答案就在http協議返回的消息頭字段,Cache-Control 和 Expires。html

 什麼是cache-control?nginx

Cache-Control header was defined as part of the HTTP/1.1 specification and supersedes previous headers (e.g. Expires) used to define response caching policies. All modern browsers support Cache-Control, hence that is all we will need.promise

簡言之,cache-control 就是定義資源文件被緩存的時間和方式的一個http頭。瀏覽器

Cache-Control 基礎緩存

Cache-Control 定義了緩存的時間和方式,安全

Cache-Control: max-age=2592000, public服務器

但瀏覽器加載一個資源時,會收到許多HTTP頭。當Cache-Control包括在其中時,瀏覽器將按照裏面的值來緩存資源。若是Cache-Control定義一個文件須要被緩存五分鐘,則五分鐘內,對該文件的重複請求將只讀取緩存。app

 

 什麼是 max-age?ide

  • "max-age"定義了緩存的時長
  • "max-age"表示在特定的秒數只能,資源將是不變的

 

max-age 的使用

max-age部分在頭部是這樣的:max-age=2592000,單位是秒。緩存時間最大隻支持1年,大於這個時間可能被忽略,詳詢RFC

一些經常使用的值:

  • 一分鐘: max-age=60
  • 一小時: max-age=3600
  • 一天: max-age=86400
  • 一週: max-age=604800
  • 一個月: max-age=2628000
  • 一年: max-age=31536000

當使用max-age去定義緩存時間時,必須考慮文件的類型和使用方式。

 

緩存指令

緩存指令部分在頭部是這樣的:

public

上面的Cache-Control頭聲明「public」。這表示這個文件將被以公開文件緩存(跟私有文件相反)

默認的,大多數文件會是公開的可緩存的,可是有時候對於敏感文檔、安全性以及用戶特有內容,公開緩存是不建議的。

有四種主要的指令

  • public
  • private
  • no-cache
  • no-store

public

"public"指令指服務器返回不只能夠被瀏覽器緩存,並且能夠被中間代理緩存,後續其餘用戶請求該資源,均可以直接使用該的緩存。

官方定義以下

 The "public" response directive indicates that any cache MAY store the response, even if the response would normally be non-cacheable or cacheable only within a private cache.

大致上,如css、js這些公共資源須要使用public緩存起來,從而加快頁面加載。

 

private

private 指令代表,服務器返回只能被用戶的瀏覽器緩存。官方定義以下:

Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of theresponse are intended for only one user and are not a valid response for requests by other users. A private (non-shared) cache MAY cache the response.

 

no-cache 

該指令若是沒有指定了一個字段名,那麼緩存每次都須要被驗證是否未變動,驗證經過則返回304,直接使用緩存。若是指定了字段名,則後續請求只須驗證該字段。

If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching. However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent the re-use of certain header fields in a response, while still allowing caching of the rest of the response.

 

no-store

該指令代表,服務器返回任什麼時候候都不能被緩存,這主要是爲了保護敏感數據。但這種方式來保護敏感信息是不可靠的。

 

The purpose of the no-store directive is to prevent the inadvertent release or retention of sensitive information (for example, on backup tapes). The no-store directive applies to the entire message, and MAY be sent either in a response or in a request. If sent in a request, a cache MUST NOT store any part of either this request or any response to it. If sent in a response, a cache MUST NOT store any part of either this response or the request that elicited it. This directive applies to both non- shared and shared caches. "MUST NOT store" in this context means that the cache MUST NOT intentionally store the information in non-volatile storage, and MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible after forwarding it.Even when this directive is associated with a response, users might explicitly store such a response outside of the caching system (e.g., with a "Save As" dialog). History buffers MAY store such responses as part of their normal operation.The purpose of this directive is to meet the stated requirements of certain users and service authors who are concerned about accidental releases of information via unanticipated accesses to cache data structures. While the use of this directive might improve privacy in some cases, we caution that it is NOT in any way a reliable or sufficient mechanism for ensuring privacy. In particular, malicious or compromised caches might not recognize or obey this directive, and communications networks might be vulnerable to eavesdropping.

 

哪些文件須要被緩存?

圖片、css、ico、js

 

如何清除緩存

添加文件指紋 好比main.js被緩存了,咱們能夠更改文件名爲main_1.js達到更新緩存的目的。

 

其餘緩存方法

Expires

Expires頭指定緩存的時間點,例如2016年11月11日。在此以前的資源的請求將直接讀取緩存。相似於max-age,只不過max-age指定的是緩存的時長,如100s, 並且max-age優先級更高。

max-age以及expires頭指定了下次更新緩存的時間,而如何獲取資源則是由Etag和Last-Modified決定。

 

條件請求

當瀏覽器緩存過時時,就會發送請求來更新緩存。條件請求會先諮詢服務器本地緩存內容是否已經變動,瀏覽器會發送緩存的一些信息給服務器,用來肯定緩存對應的服務器資源。若是緩存資源更新了則發送最新內容,不然返回304,瀏覽器繼續使用緩存。

 

 

基於時間的條件請求

若是自資源被緩存之日起,緩存內容未改變,則服務器直接返回304.開啓時間條件緩存須要服務器返回Last-Modified 響應頭,指定被緩存時的最後修改時間。

Cache-Control:public, max-age=31536000
Last-Modified: Mon, 03 Jan 2011 17:45:57 GMT

下一次,瀏覽器發送更新緩存的請求時,會使用If-Modified-Since頭來諮詢緩存對應的資源是否在這個時間之後變動過。

If-Modified-Since: Mon, 03 Jan 2011 17:45:57 GMT

若是資源在Mon, 03 Jan 2011 17:45:57 GMT 以後未改變,則服務器返回304,瀏覽器繼續使用緩存。

基於內容的條件請求

該類型的條件請求跟時間條件請求相似,只不過用的是資源的檢驗碼(checksum),好比文件的md5 hash。當沒法肯定最近修改時間時,Etag是對基於時間的條件請求很好的補充。 返回頭以下:

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

 當瀏覽器發送更新資源的請求時,將會帶上If-None-Match請求頭。

If-None-Match: "15f0fff99ed5aae4edffdd6496d7131f"

若是服務器資源的hash碼以此一致,則返回304.

 

圖例 

 

禁止緩存 

 由於IE使用的是no-cache來禁止緩存,因此返回頭以下:

Cache-Control:no-cache, no-store

 

使用nginx添加緩存控制

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {

  expires 365d;
}

 

參考:

https://varvy.com/pagespeed/cache-control.html

https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec1

https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers

相關文章
相關標籤/搜索