合理利用緩存
概述:本章主要討論了兩方面的內容。1. 瀏覽器緩存機制。 2. web實踐中如何有效利用這些緩存
瀏覽器緩存機制css
做爲web開發人員常常遇到的問題之一就是我明明修復而且部署了這個BUG爲何線上有的用戶還會出現這個問題呢?還有每次更新完咱們都會說你清除緩存試試?爲何必定要清除緩存呢,能夠確定說絕大部分用戶是不知道要清除緩存的!那咱們可否不清除緩存,最新部署的文件可以立刻就生效呢。答案是確定的,這就須要咱們花費一點時間瞭解一下緩存是怎麼工做的。 咱們能夠簡單的理解爲緩存是爲了減小網絡帶寬和優化用戶體驗而存在的。核心就是把緩存的內容保存在了本地,而不用每次都向服務端發送相同的請求,設想下每次都打開相同的頁面,而在第一次打開的同時,將下載的js、css、圖片等「保存」在了本地,而以後的請求每次都在本地讀取,效率是否是高了不少。當我用瀏覽器打開一個網頁能夠發現瀏覽器加載頁面資源的http請求返回的Status Code有如下常見的值304 Not Modified/200 OK (from disk cache)/ 200 OK。這些值表明着什麼意思呢?其實瀏覽器就是依靠請求和響應中的的頭信息來控制緩存的。下面咱們來具體分析一下。 當咱們第一次(或者ctrl+F5)打開百度,咱們會發現加載jquery.js的http請求響應字段以下
因爲是第一次或者強制刷新打開的,因此瀏覽器會忽略緩存,直接向服務器發送請求加載資源,圖中畫框的那幾個字段是與緩存相關的。它們的意義以下:html
1. cache-control:max-age=315360000:它告訴瀏覽器這個資源的緩存時間爲315360000秒(10年),那麼瀏覽器就將這個文件保存到本地磁盤緩存起來,下次你再次打開百度時,只要是再10年內瀏覽器就不向服務器發送請求加載資源了,而是直接從緩存中加載。 2. expires:Fri, 06 Nov 2026 04:20:09 GMT:它告訴瀏覽器這個資源的有效期:如今-->2026年11月6號04:20:09,在這個時間內你打開百度瀏覽器就不向服務器發送請求加載資源了,而是直接從緩存中加載。
這個是否是與cache-control功能有點重合呢,是的!Expires是HTTP1.0的東西,而Cache-Control是HTTP1.1的,規定若是max-age和Expires同時存在,前者優先級高於後者。Cache-Control的參數能夠設置不少值,譬如(參考瀏覽器緩存機制)。jquery
3. Last-Modified: Mon, 07 Nov 2016 07:51:11 GMT:標示這個響應資源的最後修改時間。 4. ETag: 告訴瀏覽器當前資源在服務器的惟一標識(生成規則由服務器以爲) 當我按下F5從新加載頁面時會獲得下面的http請求響應信息
咱們會發現瀏覽器是發送了一個http請求而不是咱們以前說的在10年以內不發送請求,而且這個請求的響應是304,就是說當我按下F5時,瀏覽器忽略了上次請求返回的cache-control和expires字段的值,它是再次發送了一個獲取資源的請求,可是此次http請求頭部包含了兩個新字段If-Modified-Since和If-None-Match(這兩個字段的值就是上次請求資源響應中包含的Last-Modified和ETag的值),這就是問題所在,服務器檢測到這兩個字段作對應的響應以下: If-Modified-Since:服務器收到請求後發現有頭If-Modified-Since則與被請求資源的最後修改時間進行比對。若最後修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最後修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省加載時間與帶寬),告知瀏覽器繼續使用所保存的cache。 If-None-Match: 服務器收到請求後發現有If-None-Match則與被請求資源的相應校驗串進行比對,決定返回200或304。
咱們會發現這兩個字段功能也有點重合,緣由以下:
1) 次Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間。
2) 若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存。
3) 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形。
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified與ETag是能夠一塊兒使用的,服務器會優先驗證ETag,一致的狀況下,纔會繼續比對Last-Modified,最後才決定是否返回304。nginx
那如今就還剩下一個問題,就是當我按下F5時,瀏覽器爲何不是直接從本地緩存中加載文件而是發送了一個http請求呢?這個是就用戶行爲與瀏覽器對緩存的控制有關
緩存總結以下
瀏覽器第一次請求:web
瀏覽器再次請求時:json
有效利用緩存
下面咱們就來講說WEB資源文件的緩存時間設置爲多少是全適的呢。gulp
如今大部分網站都是每次更新部署時,只要有修改的文件都會從新生成一個名字(如:gulp打包[http://www.xxx.tv/dist/hr20170117/js/main-f3d7137ecb.js],HTML文件除外),至關於有更改的文件都有新的URL.針對這種狀況,咱們能夠進行以下設置
HTML文件能夠設置爲max-age爲0,那麼用戶每次打開網頁都會向服務器詢問這個網頁有沒有更改,若是有更改用戶就可以加載最新的文件。瀏覽器
CSS/JS文件能夠設置爲30天或者1年。
下面爲對應的nginx配置
location ~ .*.(js|css)?${緩存
expires 1M;
}服務器
~* .(?:manifest|appcache|html?|xml|json)$ {
expires -1;}