經過網絡獲取內容既速度緩慢又開銷巨大。較大的響應須要在客戶端與服務器之間進行屢次往返通訊,這會延遲瀏覽器得到和處理內容的時間,還會增長訪問者的流量費用。所以,緩存並重複利用以前獲取的資源的能力成爲性能優化的一個關鍵方面。css
好在每一個瀏覽器都自帶了 HTTP 緩存實現功能。您只須要確保每一個服務器響應都提供正確的 HTTP 標頭指令,以指示瀏覽器什麼時候能夠緩存響應以及能夠緩存多久。git
注:若是您在應用中使用 Webview 來獲取和顯示網頁內容,可能須要提供額外的配置標誌,以確保 HTTP 緩存獲得啓用、其大小根據用例進行了合理設置而且緩存將持久保存。務必查看平臺文檔並確認您的設置!github
當服務器返回響應時,還會發出一組 HTTP 標頭,用於描述響應的內容類型、長度、緩存指令、驗證令牌等。例如,在上圖的交互中,服務器返回一個 1024 字節的響應,指示客戶端將其緩存最多 120 秒,並提供一個驗證令牌(「x234dff」),可在響應過時後用來檢查資源是否被修改。瀏覽器
假定在首次獲取資源 120 秒後,瀏覽器又對該資源發起了新的請求。首先,瀏覽器會檢查本地緩存並找到以前的響應。遺憾的是,該響應現已過時,瀏覽器沒法使用。此時,瀏覽器能夠直接發出新的請求並獲取新的完整響應。不過,這樣作效率較低,由於若是資源未發生變化,那麼下載與緩存中已有的徹底相同的信息就毫無道理可言!緩存
這正是驗證令牌(在 ETag 標頭中指定)旨在解決的問題。服務器生成並返回的隨機令牌一般是文件內容的哈希值或某個其餘指紋。客戶端不須要了解指紋是如何生成的,只需在下一次請求時將其發送至服務器。若是指紋仍然相同,則表示資源未發生變化,您就能夠跳過下載。性能優化
在上例中,客戶端自動在「If-None-Match」 HTTP 請求標頭內提供 ETag 令牌。服務器根據當前資源覈對令牌。若是它未發生變化,服務器將返回「304 Not Modified」響應,告知瀏覽器緩存中的響應未發生變化,能夠再延用 120 秒。請注意,您沒必要再次下載響應,這節約了時間和帶寬。服務器
做爲網絡開發者,您如何利用高效的從新驗證?瀏覽器會替咱們完成全部工做:它會自動檢測以前是否指定了驗證令牌,它會將驗證令牌追加到發出的請求上,而且它會根據從服務器接收的響應在必要時更新緩存時間戳。咱們惟一要作的就是確保服務器提供必要的 ETag 令牌。檢查您的服務器文檔中有無必要的配置標誌。markdown
提示:HTML5 Boilerplate 項目包含全部最流行服務器的配置文件樣例,其中爲每一個配置標誌和設置都提供了詳細的註解。在列表中找到您喜好的服務器,查找合適的設置,而後複製/確認您的服務器配置了推薦的設置。網絡
從性能優化的角度來講,最佳請求是無需與服務器通訊的請求:您能夠經過響應的本地副本消除全部網絡延遲,以及避免數據傳送的流量費用。爲實現此目的,HTTP 規範容許服務器返回 Cache-Control 指令,這些指令控制瀏覽器和其餘中間緩存如何緩存各個響應以及緩存多久。函數
Cache-Control 標頭是在 HTTP/1.1 規範中定義的,取代了以前用來定義響應緩存策略的標頭(例如 Expires)。全部現代瀏覽器都支持 Cache-Control,所以,使用它就夠了。
「no-cache」和「no-store」 「no-cache」表示必須先與服務器確認返回的響應是否發生了變化,而後才能使用該響應來知足後續對同一網址的請求。所以,若是存在合適的驗證令牌 (ETag),no-cache 會發起往返通訊來驗證緩存的響應,但若是資源未發生變化,則可避免下載。 相比之下,「no-store」則要簡單得多。它直接禁止瀏覽器以及全部中間緩存存儲任何版本的返回響應,例如,包含我的隱私數據或銀行業務數據的響應。每次用戶請求該資產時,都會向服務器發送請求,並下載完整的響應。
「public」與「private」 若是響應被標記爲「public」,則即便它有關聯的 HTTP 身份驗證,甚至響應狀態代碼一般沒法緩存,也能夠緩存響應。大多數狀況下,「public」不是必需的,由於明確的緩存信息(例如「max-age」)已表示響應是能夠緩存的。 相比之下,瀏覽器能夠緩存「private」響應。不過,這些響應一般只爲單個用戶緩存,所以不容許任何中間緩存對其進行緩存。例如,用戶的瀏覽器能夠緩存包含用戶私人信息的 HTML 網頁,但 CDN 卻不能緩存。
「max-age」 指令指定從請求的時間開始,容許獲取的響應被重用的最長時間(單位:秒)。例如,「max-age=60」表示可在接下來的 60 秒緩存和重用響應。
按照以上決策樹爲您的應用使用的特定資源或一組資源肯定最佳緩存策略。在理想的狀況下,您的目標應該是在客戶端上緩存儘量多的響應,緩存儘量長的時間,而且爲每一個響應提供驗證令牌,以實現高效的從新驗證。
Cache-Control | 指令和說明 |
---|---|
max-age=86400 | 瀏覽器以及任何中間緩存都可將響應(若是是「public」響應)緩存長達 1 天(60 秒 x 60 分鐘 x 24 小時)。 |
private, max-age=600 | 客戶端的瀏覽器只能將響應緩存最長 10 分鐘(60 秒 x 10 分鐘)。 |
no-store | 不容許緩存響應,每次請求都必須完整獲取。 |
根據 HTTP Archive,在排名最高的 300,000 個網站(按照 Alexa 排名)中,全部下載的響應中幾乎有半數可由瀏覽器緩存,這能夠大量減小重複的網頁瀏覽和訪問。固然,這並不意味着您的特定應用有 50% 的資源能夠緩存。一些網站的資源 90% 以上均可以緩存,而其餘網站可能有許多私密或時效要求高的數據根本沒法緩存。
請審覈您的網頁,肯定哪些資源能夠緩存,並確保它們返回正確的 Cache-Control 和 ETag 標頭。
客戶端緩存和快速更新?您能夠在資源內容發生變化時更改它的網址,強制用戶下載新響應。一般狀況下,能夠經過在文件名中嵌入文件的指紋或版本號來實現 - 例如 style.x234dff.css。
不存在什麼最佳緩存策略。您須要根據通訊模式、提供的數據類型以及應用特定的數據更新要求,爲每一個資源定義和配置合適的設置,以及總體的「緩存層次結構」。
在制定緩存策略時,您須要牢記下面這些技巧和方法:
使用一致的網址 若是您在不一樣的網址上提供相同的內容,將會屢次獲取和存儲這些內容。提示:請注意,網址區分大小寫。
確保服務器提供驗證令牌 (ETag) 有了驗證令牌,當服務器上的資源未發生變化時,就不須要傳送相同的字節。
肯定中間緩存能夠緩存哪些資源 對全部用戶的響應徹底相同的資源很是適合由 CDN 以及其餘中間緩存進行緩存。
爲每一個資源肯定最佳緩存週期 不一樣的資源可能有不一樣的更新要求。爲每一個資源審覈並肯定合適的 max-age。
肯定最適合您的網站的緩存層次結構 您能夠經過爲 HTML 文檔組合使用包含內容指紋的資源網址和短期或 no-cache 週期,來控制客戶端獲取更新的速度。
最大限度減小攪動 某些資源的更新比其餘資源頻繁。若是資源的特定部分(例如 JavaScript 函數或 CSS 樣式集)會常常更新,能夠考慮將其代碼做爲單獨的文件提供。這樣一來,每次獲取更新時,其他內容(例如變化不是很頻繁的內容庫代碼)能夠從緩存獲取,從而最大限度減小下載的內容大小。
打開頁面方式 | IE6(httpwatch) | FF3.5(httpfox) |
---|---|---|
1. 第一次打開頁面 | 200 | 200 |
2. 重啓瀏覽器打開頁面 | cache,即時發生資源修改也不會從新請求 | cache,即時發生資源修改也不會從新請求 |
3. F5刷新 | 304,發生修改的資源狀態爲200 | 304,發生修改的資源狀態爲200 |
4. Ctrl+F5刷新 | 200,強制全新請求 | 200 |
5. 後退 | cache,簡單直接地從緩存加載 | cache,簡單直接地從緩存加載 |
6. 在已訪問頁面地址欄回車 | cache | cache |