咱們常常經過緩存技術來加快網站的訪問速度,從而提高用戶體驗。HTTP協議中也規定了一些和緩存相關的Header,來容許瀏覽器或共享高速緩存緩存資源。這些Header包括:瀏覽器
以上Header又能夠分紅兩種類型:緩存
本文將會分別介紹這四種配置的做用以及可能產生的影響。服務器
Last-Modified:服務器在響應請求時,告知瀏覽器資源的最後修改時間。函數
If-Modified-Since:瀏覽器再次發送請求時,會經過此Header通知服務器在上次請求時所獲得的資源最後修改時間。服務器會將If-Modified-Since與被請求資源的最後修改時間進行比對。若資源的最後修改時間晚於If-Modified-Since,表示資源已被改動,則響最新的資源,返回200狀態碼;若資源的最後修改時間早於或等於If-Modified-Since,表示瀏覽器端的資源已是最新版本,響應304狀態碼,通知瀏覽器繼續使用緩存中的資源。性能
ETag:服務器分配給資源的惟一標識符,資源被修改後,ETag也會隨之發生變化。測試
If-None-Match:瀏覽器再次發送請求時,會經過此Header通知服務器已緩存資源的ETag。服務器會將If-None-Match與被請求資源的最新ETag進行比對。若不相同,表示資源已被改動,則響應最新的資源,返回200狀態碼;若值相同,則直接響應304狀態碼,通知瀏覽器繼續使用緩存中的資源。網站
服務器能夠經過此Header向瀏覽器傳遞一個具體的時間(格林威治格式,例如:Thu, 19 Jul 2018 07:43:05 GMT) ,來明確地宣告資源的有效期。在資源過時以前,瀏覽器再也不發送請求,而是直接從緩存中讀取數據。只有當資源過時以後,瀏覽器纔會再次向服務器請求該資源。阿里雲
服務器使用此Header來向客戶端建議緩存策略,它有一下幾個可選值:code
max-age=秒:告知瀏覽器緩存的有效時長,在該時間內瀏覽器將直接從緩存中讀取數據。cdn
s-maxage=秒:做用同max-age,可是隻對共享高速緩存(如CDN)有效,對瀏覽器無效。
no-cache:告知瀏覽器不要直接使用緩存,而是必須向服務器發送請求。
no-store:告知瀏覽器不要緩存本次請求和響應的任何信息。
public:宣告任何緩存媒介均可以緩存該響應。
private:宣告該響應只容許個體客戶端(如瀏覽器)去緩存,而不容許共享高速緩存(如CDN)去緩存。
在上面的介紹中咱們瞭解到瀏覽器會根據max-age設置的時間進行緩存。而經過研究發現CDN也會識別源站響應頭中Cache-Control屬性,根據max-age設置的時間進行緩存,可是,若是源站同時設置了s-maxage和max-age,那麼CDN會優先採用s-maxage。
下面經過圖例來展現一下這些可選值的效果。
首先了解一下瀏覽器是怎樣根據max-age進行緩存的:
從上圖不難發現,服務器在Header中返回了Cache-Control: max-age=100後,瀏覽器成功緩存100秒,該時間段內的請求都從直接以本地緩存來響應。
那麼,服務器在Header中返回Cache-Control:s-maxage=100時,又會對瀏覽器產生什麼樣的影響呢?
如上圖所示,瀏覽器沒有采起任何緩存策略,這是由於s-maxage面向的是共享高速緩。
上面這兩個例子很容易理解,在現實世界中,爲了加快網站響應速度,咱們可能會在瀏覽器和服務器之間引入CDN服務。瀏覽器的請求會先到達CDN,而後CDN判斷是從緩存中讀取數據仍是回源到服務器。接下來,讓咱們看看max-age和s-maxage會對CDN的緩存策略帶來哪些影響。
能夠看出CDN也會利用max-age來緩存,因此在100秒內強制刷新瀏覽器時,CDN會直接用緩存來響應。
若是服務器使用了s-maxage又會如何呢?
不難發現CDN對max-age和s-maxage採起了一樣的緩存策略,但瀏覽器並不會根據s-maxage來進行緩存。
CDN供應商的特殊規則
咱們分別測試了阿里雲和騰訊雲的CDN對Cache-Control的支持狀況,發現他們都有一些獨特的規則。
阿里雲CDN能夠在控制檯裏設置Cache-Control,該設置會覆蓋源服務器的Cache-Control。
騰訊雲CDN雖然沒有再控制檯提供覆蓋Cache-Control的功能,但其規則卻一點也不簡單,在使用的時候必定要特別注意:
若是同時設置了這些Header,瀏覽器和高速共享緩存會按照下面的優先級進行緩存:
Cache-Control > Expires > ETag > Last-Modified
也就是說,Cache-Control不只是強緩存,並且擁有最高的優先級,咱們能夠爲不常常發生變化的資源應用該Header來提高響應時間。
Ada提供了UI腳手架和API腳手架,這兩類腳手架的服務器端入口文件分別爲index.server.js和index.js,咱們只須要在入口文件的請求處理函數中爲響應添加適當的Header,便可通知客戶端進行響應的緩存,好比:
// 設置CDN緩存300秒,瀏覽器緩存200秒 ctx.response.headers.set('Cache-Control', public,s-maxage=300,max-age=200
) 在爲請求添加緩存Header以前,應該先爲其制定適當的緩存策略,須要考慮該URL是否適合緩存(數據是否特定於用戶)以及須要緩存的時長等等。
總結 經過使用這些HTTP Header,咱們能夠主動影響瀏覽器甚至CDN的緩存策略,從而減小請求數量,提高網頁性能,減輕服務器壓力。
Ada的靈活機制能讓咱們爲不一樣的URL設置不一樣的緩存策略,可以更有針對性地進行主動緩存。