瀏覽器緩存 是瀏覽器將用戶請求過的靜態資源(html、css、js),存儲到電腦本地磁盤中,當瀏覽器再次訪問時,就能夠直接從本地加載了,不須要再去服務端請求了。css
但也不是說緩存沒有缺點,若是處理不當,可能會致使服務端代碼更新了,可是用戶卻仍是老頁面。因此前端們要針對項目中各個資源的實際狀況,作出合理的緩存策略。html
緩存的優勢:前端
這裏先介紹一下瀏覽器緩存資源的一個大概的流程。nginx
咱們能夠認爲,瀏覽器裏有一個專門存放緩存規則的一個數據庫,也能夠說是一個映射表,把緩存資源信息,同電腦磁盤中的實際文件的地址,對應起來。(大概意思,別較真)chrome
而這個緩存規則的表,在瀏覽器中是能夠看到的: chrome://cache/數據庫
不過我升級了瀏覽器以後,就很差使了,可是找到了 chrome://net-internals/#httpCache ,不知道是否是就是原來的,知道的同窗也能夠反饋一下後端
瀏覽器第一次請求資源時瀏覽器
上面所說的 緩存規則,就是聲明所請求的這個資源,要採起哪一種緩存策略?緩存多長時間?等等。。。而這個規則,是在http的header中的返回來的。緩存
注意: 是response header ,而不是 request header !!!服務器
而實際上, request header 中也會攜帶規則信息,下面會講,要區分 request 和 response
強緩存和協商緩存。
簡單粗暴,若是資源沒過時,就取緩存,若是過時了,則請求服務器。
如何判斷資源是否過時呢,也就是說強緩存的規則怎麼看?
主要是看 response headers 中的 Cache-Control 的值,圖中的max-age = 31xxxxxxx,就是說在這些秒內,都直接使用緩存,超過了就繼續請求服務器
而和 Cache-Control 並列的,還有一個 Expires ,已經基本淘汰了,因此不用管
Cache-Control 的幾個取值含義:
private: 僅瀏覽器能夠緩存
public: 瀏覽器和代理服務器均可以緩存(對於private和public,前端能夠認爲同樣,不用深究)
max-age=xxx 過時時間(重要)
no-cache 不進行強緩存(重要)
no-store 不強緩存,也不協商緩存,基本不用,緩存越多才越好呢
注意:規則能夠同時多個
因此,對於強緩存,咱們主要研究 Cache-Control 中的 max-age 和 no-cache
因此,判斷該資源是否命中強緩存,就看 response 中 Cache-Control 的值,若是有max-age=xxx秒,則命中強緩存。若是Cache-Control的值是no-cache,說明沒命中強緩存,走協商緩存。
強緩存流程:
因此強緩存步驟已經很清晰了:
觸發條件:
也就是說,無論怎樣,均可能最後要進行協商緩存(no-store除外)
這個圖,雖然強緩存命中,可是也有 ETag 和 Last-Modified ,這兩個就是協商緩存的相關規則。雖然以前的強緩存流程和他倆沒關。。。
ETag:每一個文件有一個,改動文件了就變了,能夠看似md5
Last-Modified:文件的修改時間
也就是說,每次http返回來 response header 中的 ETag和 Last-Modified,在下次請求時在 request header 就把這兩個帶上(可是名字變了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服務端把你帶過來的標識,資源目前的標識,進行對比,而後判斷資源是否更改了。
這個過程是循環往復的,即緩存表在每次請求成功後都會更新規則。
1. 第n次請求成功時:
2. 緩存表中更新該資源的 ETag 值
3. 第n+1次請求:
從緩存表中取該資源最新的ETag,而後加在 request header 中, 注意變名字了,由 ETag -- > If-None-Match
圖:
因此協商緩存步驟總結:
注意:協商緩存不管若是,都要向服務端發請求的,只不過,資源未更改時,返回的只是header信息,因此size很小;而資源有更改時,還要返回body數據,因此size會大。
0. 怎麼配置資源的緩存規則
能夠有後端服務器配置,也能夠在nginx中配置,稍後會更新一張nginx的配置
1. 爲何要有Etag
你可能會以爲使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,爲何還須要Etag呢?HTTP1.1中Etag的出現(也就是說,ETag是新增的,爲了解決以前只有If-Modified的缺點)主要是爲了解決幾個Last-Modified比較難解決的問題:
一些文件也許會週期性的更改,可是他的內容並不改變(僅僅改變的修改時間),這個時候咱們並不但願客戶端認爲這個文件被修改了,而從新GET;
某些文件修改很是頻繁,好比在秒如下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改沒法判斷(或者說UNIX記錄MTIME只能精確到秒);
某些服務器不能精確的獲得文件的最後修改時間。
2. 強緩存與協商緩存的區別能夠用下表來表示:
3. 用戶行爲對緩存的影響
即:F5 會 跳過強緩存規則,直接走協商緩存;;;Ctrl+F5 ,跳過全部緩存規則,和第一次請求同樣,從新獲取資源
借兩個圖