爲了優化性能,使用緩存是一種比較常見的手段。那麼如何實現緩存以及如何避免緩存呢,都是要探討的話題。能夠從三個部分:http 緩存、cookie、localStorage&sessionStorage 來重點講述緩存實現的原理、過程以及實現的方式。因爲篇幅緣由,本篇重點講述 http 緩存。css
緩存命中: 使用已有的副本爲到達的請求提供資源而不用從服務器中獲取資源。
緩存未命中: 達緩存的請求沒有副本可用,而被轉發給原始服務器,與緩存命中相反。
CHP: Cache Hit Percentage,緩存提供服務請求所佔有的比例,緩存的文件個數/請求資源個數。
下圖是打開百度資源後所請求的資源(部分)狀況:html
能夠看到其中有兩個資源是從服務器中獲取的,其他是從緩存中獲取,那麼其CHP值爲:80%。web
所謂的強緩存是指請求資源的時候不須要發送 http 向服務器發送請求,直接從客戶端獲取資源。實現的方式是有 http 的 Expires,Cache-Control兩個response header實現的。ajax
Expires是 http 1.0 提出的一個 header,其值是一個資源有效期的絕對時間,實現緩存的過程以下: express
Expires的值爲一個絕對時間,當客戶端改變了時間或者時區問題,會致使緩存失效;所以在http 1.1 中引入了Cache-Control。瀏覽器
Cache-Control與Expires同時存在的時候Cache-Control的優先級大於Expires緩存
Cache-Control 實現的過程與 Expires 相似,其常見的有三個值: 服務器
Cache-Control:max-ag=0 與 Cache-Control:no-cache 在使用效果上沒有多大的區別,區別在於服務器掛了是否可使用以前的緩存的response 即 max-age=0 能夠看到以前緩存的內容,頁面正常顯示以前的內容而 no-cache 則返回錯誤5xx狀態碼cookie
上面講述利用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,進行統一配置。
協商緩存是在用戶強緩存失敗的狀況下,向服務器端進行再驗證。它與強緩存的區別在於會向服務器發送請求,可是不會獲取資源,瀏覽器端請求的資源仍是從緩存中獲取。其實現有兩對首部:【Last-Modified,If-Modified-Since】、【ETag、If-None-Match】其中以【Last-Modified,If-Modified-Since】爲例,講解實現的過程。
開發側
(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/...