在上一篇文章中,咱們講到形成網絡性能降低的主要緣由是延遲,而非帶寬。那麼爲了更好地讓咱們的網站能快速響應用戶的請求,咱們就必須對一些經常使用資源進行緩存,
以避免每次用戶訪問都請求一遍,這也是網站性能優化比較重要的一個環節。css
現代瀏覽器都自帶了HTTP緩存實現功能,咱們所要作的只是確保咱們正確地設置了HTTP響應頭,以便指示瀏覽器什麼時候緩存響應以及緩存多久。瀏覽器
首先說明一點,緩存並非說瀏覽器不會對該資源再次發起請求,每種緩存機制都有本身的過時策略,咱們經常看到的304狀態碼就表面該資源已被緩存了,但瀏覽器不知道有沒有過時,
再次使用該資源的時候,會向服務器發起請求驗證一遍,若是緩存資源有效,則會返回304狀態碼。最壞的狀況下,則是該資源過時了,還得從新發起一次請求去獲取。另外一種則是瀏覽
器連問都不問服務器,直接就從本地硬盤讀取,此時能夠看到瀏覽器給出的響應是200(from disk cache)。緩存
假設咱們有一份css資源,咱們在獲取該資源一段時間後又刷新了頁面,這時瀏覽器就會檢查本地資源並查找以前的響應。但遺憾的是,該響應已通過期。此時,瀏覽器能夠直接發起請求
從新去獲取一份新的數據,但這樣作效率實在是過低了。若資源自己改變了還好說,但若資源自己並無改變呢,從新獲取一份數據成本過高。性能優化
這時ETag就是用來解決這個問題的,ETag能夠看作是這個文件的hash值,只要文件內容沒有改變,ETag值則不會變。客戶端徹底不須要了解ETag是怎麼生成的,只須要在下一次請求的
時候將ETag帶上便可(瀏覽器發起請求時,if-None-Match中的值就是該ETag值),若該ETag與服務器匹配,則會返回304,告訴瀏覽器可使用該緩存,從而跳過再次下載過程。服務器
Cache-Control指令控制誰在什麼條件下能夠緩存響應以及能夠緩存多久,如上面所說,有些資源咱們能夠直接從本地磁盤獲取(from disk cache),而無需再次發起請求詢問服務器,這
即是Cache-Control的做用。Cache-Control是HTTP/1.1規範中定義的,如今基本用它來取代Expires。網絡
"no-cache"表示必須與服務器確認返回的響應是否發生了變化,而後才能使用該響應來知足後續對同一資源的請求。該值能夠配合ETag來使用,瀏覽器經過請求If-None-Match來向服務器
驗證該資源是否過時,若資源未發生變化,則避免下載。性能
"no-store"則表示不管什麼狀況下,瀏覽器都不得緩存該資源,即使存在ETag也同樣,每次都得從服務器中獲取。優化
若是響應被標記爲"public",則即便它有關聯的 HTTP 身份驗證,甚至響應狀態代碼一般沒法緩存,也能夠緩存響應。大多數狀況下,「public」不是必需的,由於明確的緩存信息(例如「max-age」)
已表示響應是能夠緩存的。網站
"private"表示響應只爲單個用戶緩存,所以不容許中間緩存對其進行緩存。例如,用戶瀏覽器能夠緩存包含用戶私人信息的HTML網頁,但CDN則不能夠。spa
該值是Cache-Control中用得比較多的一個值,表示從請求的時間開始,容許獲取的響應被緩存的最長時間(單位:秒)。例如,max-age設置爲100,則表示該資源能夠緩存100秒,100秒後,再次
請求該資源,瀏覽器則會攜帶ETag去詢問服務器該資源是否過時。在該資源未過時時,訪問該資源,瀏覽器則從本地磁盤獲取,不會發起任何網絡請求。
如上圖所示,若是資源不須要緩存,咱們設置Cache-Control的值爲no-store;若是資源須要緩存且每次都得向服務器驗證,則爲no-cache;若是中間設備能夠緩存,設置爲public,中間設備不
可緩存,設置爲private;若是緩存有時間限制,咱們設置max-age的值。private與public的值能夠與max-age同時使用,中間用分號隔開。
Expires頭指定了一個日期/時間,在這個日期/時間以後,HTTP響應被認爲是過期的,一個無效的日期,例如0也表示該資源過期。若是還設置了max-age,則該請求頭會被忽略。
使用緩存最好的方式就是ETag配合Cache-Control,並設置相應的max-age,通常狀況下,再也不建議使用Expires頭。若是資源許久都不更新,max-age能夠設置比較長的時間,可是這樣會有個問題就是在緩存期間,該文件發生改變,但相應的客戶端卻仍是在使用舊版本,解決的方法就是每一個文件都帶一個相應內容的hash值做爲文件名。這樣,即便文件緩存了,也能夠獲得更新。