http 緩存小結

爲了優化性能,使用緩存是一種比較常見的手段。那麼如何實現緩存以及如何避免緩存呢,都是要探討的話題。能夠從三個部分:http 緩存、cookie、localStorage&sessionStorage 來重點講述緩存實現的原理、過程以及實現的方式。因爲篇幅緣由,本篇重點講述 http 緩存。css

1.基本概念

緩存命中: 使用已有的副本爲到達的請求提供資源而不用從服務器中獲取資源。 
緩存未命中: 達緩存的請求沒有副本可用,而被轉發給原始服務器,與緩存命中相反。 
CHP: Cache Hit Percentage,緩存提供服務請求所佔有的比例,緩存的文件個數/請求資源個數。 
下圖是打開百度資源後所請求的資源(部分)狀況:
clipboard.pnghtml

能夠看到其中有兩個資源是從服務器中獲取的,其他是從緩存中獲取,那麼其CHP值爲:80%。web

2.強緩存

所謂的強緩存是指請求資源的時候不須要發送 http 向服務器發送請求,直接從客戶端獲取資源。實現的方式是有 http 的 Expires,Cache-Control兩個response header實現的。ajax

2.1 Expires

Expires是 http 1.0 提出的一個 header,其值是一個資源有效期的絕對時間,實現緩存的過程以下: express

  • 瀏覽器發送請求,服務器在response 的header中加入Expires,並將資源返回給瀏覽器; 
  • 瀏覽器獲取到資源後,會存儲一個資源的副本,並將EXpires中的時間進行保存; 
  • 當再次進行資源請求的時候,瀏覽器會將當前的請求時間與以前存儲的時間進行比較; 
  • 若是請求的時間在有效期以內,則直接使用副本,反之會向服務器發送資源而且從新更新資源的有效期

Expires的值爲一個絕對時間,當客戶端改變了時間或者時區問題,會致使緩存失效;所以在http 1.1 中引入了Cache-Control。瀏覽器

Cache-Control與Expires同時存在的時候Cache-Control的優先級大於Expires緩存

2.2 Cache-Control

Cache-Control 實現的過程與 Expires 相似,其常見的有三個值: 服務器

  • max-age: 以秒爲單位,表示資源緩存的相對時間。瀏覽器再次進行請求的時候,會將上次請求的時間與max-age相對時間求和,在與如今請求的時間相比較,若是在計算的時間範圍內,則緩存可用; 
  • no-cache: 表示資源能夠進行緩存,可是在下次進行使用的時候,必須去服務器端進行再驗證。若是返回的response status 是304,那麼就是從緩存中獲取資源,若是是200 則從服務器端獲取資源; 
  • no-store: 資源不能進行本地緩存,再次請求資源的時候,須要去服務器從新獲取資源。

Cache-Control:max-ag=0 與 Cache-Control:no-cache 在使用效果上沒有多大的區別,區別在於服務器掛了是否可使用以前的緩存的response 即 max-age=0 能夠看到以前緩存的內容,頁面正常顯示以前的內容而 no-cache 則返回錯誤5xx狀態碼cookie

2.3 如何加入Expires與Cache-Control頭部

上面講述利用Expires與Cache-Control如何實現緩存的,那怎麼樣在請求資源的時候加入這兩個header呢,有如下兩種方式: 
(1) 經過代碼的方式,在web服務器返回的響應中添加響應頭部,如在 Express 框架中使用 setHeader 加入,代碼以下:session

const picMap = {
 'logo.png': 'no-store',
 'avatar.png': 'no-cache',
 'background.png': 'max-age: 36000'
}
app.use(express.static(publicPath, setHeaders(res, filePath, stat) {
 let baseName = path.basename(filePath);
 picMap[baseName] && res.set('Cache-Control', picMap[baseName])
}));

(2) 經過配置web服務器的方式,在服務器配置文件中加入 Expires 與 Cache-Control,進行統一配置。

3.協商緩存

協商緩存是在用戶強緩存失敗的狀況下,向服務器端進行再驗證。它與強緩存的區別在於會向服務器發送請求,可是不會獲取資源,瀏覽器端請求的資源仍是從緩存中獲取。其實現有兩對首部:【Last-Modified,If-Modified-Since】、【ETag、If-None-Match】其中以【Last-Modified,If-Modified-Since】爲例,講解實現的過程。

  • 瀏覽器第一次請求一個資源,服務器會將資源以及資源的最後修改時間(時間放入Last-Modified)發送給瀏覽器;
  • 瀏覽器獲取資源,將資源以及修改時間進行保存;
  • 瀏覽器再次請求相同資源的同時,在請求的頭部加入 If-Modified-Since,其值爲上一次請求保存的時間;
  • 服務器會將資源最後修改的時間與 If-Modified-Since 相比較,若是時間一致就返回 304 狀態碼,反之則發送新的資源給服務器。

4.緩存避免

開發側
(1) 給資源加上一個動態的參數,如css/index.css?v=0.1 
(2) 若是緩存問題出如今 ajax 請求中,能夠給請求地址添加隨機數;

用戶側
(1) F5:cache-control:max-age=0 
(2) Ctrl+F5:請求的時候不帶上任何緩存頭

參考文獻
[1] 《http權威指南》。 
[2] https://www.cnblogs.com/lyzg/...

相關文章
相關標籤/搜索