1. 程式人生 > >HTML5快取機制淺析:移動端Web載入效能優化

HTML5快取機制淺析:移動端Web載入效能優化

1. HTML5快取機制介紹

HTML5是新一代的HTML標準,加入很多新的特性。離線儲存(也可稱為快取機制)是其中一個非常重要的特性。HTML5引入的離線儲存,這意味著Web應用可進行快取,並可在沒有因特網連線時進行訪問。

HTML5應用程式快取為應用帶來三個優勢:

  • 離線瀏覽:使用者可在應用離線時使用它們;
  • 速度:已快取資源載入得更快;
  • 減少伺服器負載:瀏覽器將只從伺服器下載更新過或更改過的資源。

根據標準,到目前為止,HTML5一共有6種快取機制,有些是之前已有,有些是HTML5才新加入的。

  1. 瀏覽器快取機制;
  2. Dom Storgage(Web Storage)儲存機制;
  3. Web SQL Database儲存機制;
  4. Application Cache(AppCache)機制;
  5. Indexed Database (IndexedDB);
  6. File System API。

下面我們首先分析各種快取機制的原理、用法及特點;然後針對Android移動端Web效能載入優化的需求,看如何適當利用快取機制來提高Web的載入效能。

2. HTML5快取機制原理分析

2.1 瀏覽器快取機制

瀏覽器快取機制是指通過HTTP協議頭裡的Cache-Control(或Expires)和Last-Modified(或Etag)等欄位來控制檔案快取的機制。這應該是Web中最早的快取機制了,是在HTTP協議中實現的,有點不同於Dom Storage、AppCache等快取機制,但本質上是一樣的。可以理解為,一個是協議層實現的,一個是應用層實現的。

Cache-Control用於控制檔案在本地快取有效時長。最常見的,比如伺服器回包:Cache-Control:max-age=600表示檔案在本地應該快取,且有效時長是600秒(從發出請求算起)。在接下來600秒內,如果有請求這個資源,瀏覽器不會發出HTTP請求,而是直接使用本地快取的檔案。

Last-Modified是標識檔案在伺服器上的最新更新時間。下次請求時,如果檔案快取過期,瀏覽器通過If-Modified-Since欄位帶上這個時間,傳送給伺服器,由伺服器比較時間戳來判斷檔案是否有修改。如果沒有修改,伺服器返回304告訴瀏覽器繼續使用快取;如果有修改,則返回200,同時返回最新的檔案。

Cache-Control通常與Last-Modified一起使用。一個用於控制快取有效時間,一個在快取失效後,向服務查詢是否有更新。

Cache-Control還有一個同功能的欄位:Expires。Expires的值一個絕對的時間點,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT,表示在這個時間點之前,快取都是有效的。

Expires是HTTP1.0標準中的欄位,Cache-Control是HTTP1.1標準中新加的欄位,功能一樣,都是控制快取的有效時間。當這兩個欄位同時出現時,Cache-Control是高優化級的。

Etag也是和Last-Modified一樣,對檔案進行標識的欄位。不同的是,Etag的取值是一個對檔案進行標識的特徵字串。在向伺服器查詢檔案是否有更新時,瀏覽器通過If-None-Match欄位把特徵字串傳送給伺服器,由伺服器和檔案最新特徵字串進行匹配,來判斷檔案是否有更新。沒有更新回包304,有更新回包200。Etag和Last-Modified可根據需求使用一個或兩個同時使用。兩個同時使用時,只要滿足基中一個條件,就認為檔案沒有更新。

另外有兩種特殊的情況:

  • 手動重新整理頁面(F5),瀏覽器會直接認為快取已經過期(可能快取還沒有過期),在請求中加上欄位:Cache-Control:max-age=0,發包向伺服器查詢是否有檔案是否有更新。
  • 強制重新整理頁面(Ctrl+F5),瀏覽器會直接忽略本地的快取(有快取也會認為本地沒有快取),在請求中加上欄位:Cache-Control:no-cache(或 Pragma:no-cache),發包向服務重新拉取檔案。

下面是通過Google Chrome瀏覽器(用其他瀏覽器+抓包工具也可以)自帶的開發者工具,對一個資原始檔不同情況請求與回包的截圖。

首次請求:200

快取有效期內請求:200(from cache)

快取過期後請求:304(Not Modified)

一般瀏覽器會將快取記錄及快取檔案存在本地Cache資料夾中。Android下App如果使用Webview,快取的檔案記錄及檔案內容會存在當前App的Data目錄中。

分析:Cache-Control和Last-Modified一般用在Web的靜態資原始檔上,如JS、CSS 和一些影象檔案。通過設定資原始檔快取屬性,對提高資原始檔載入速度,節省流量很有意義,特別是行動網路環境。但問題是:快取有效時長該如何設定?如果設定太短,就起不到快取的使用;如果設定的太長,在資原始檔有更新時,瀏覽器如果有快取,則不能及時取到最新的檔案。

Last-Modified需要向伺服器發起查詢請求,才能知道資原始檔有沒有更新。雖然伺服器可能返回304告訴沒有更新,但也還有一個請求的過程。對於行動網路,這個請求可能是比較耗時的。有一種說法叫“消滅304”,指的就是優化掉304的請求。

抓包發現,帶if-Modified-Since欄位的請求,如果伺服器回包304,回包帶有Cache-Control:max-age或Expires欄位,檔案的快取有效時間會更新,就是檔案的快取會重新有效。304回包後如果再請求,則又直接使用快取檔案了,不再向伺服器查詢檔案是否更新了,除非新的快取時間再次過期。

另外,Cache-Control與Last-Modified是瀏覽器核心的機制,一般都是標準的實現,不能更改或設定。以QQ瀏覽器的X5為例,Cache-Control與Last-Modified快取不能禁用。快取容量是12MB,不分Host,過期的快取會最先被清除。如果都沒過期,應該優先清最早的快取或最快到期的或檔案大小最大的;過期快取也有可能還是有效的,清除快取會導致資原始檔的重新拉取。

還有,瀏覽器,如X5,在使用快取檔案時,是沒有對快取檔案內容進行校驗的,這樣快取檔案內容被修改的可能。

分析發現,瀏覽器的快取機制還不是非常完美的快取機制。完美的快取機制應該是這樣的:

  1. 快取檔案沒更新,儘可能使用快取,不用和伺服器互動;
  2. 快取檔案有更新時,第一時間能使用到新的檔案;
  3. 快取的檔案要保持完整性,不使用被修改過的快取檔案;
  4. 快取的容量大小要能設定或控制,快取檔案不能因為儲存空間限制或過期被清除。 以X5為例,第1、2條不能同時滿足,第3、4條都不能滿足。

在實際應用中,為了解決Cache-Control快取時長不好設定的問題,以及為了“消滅304”,Web前端採用的方式是:

  1. 在要快取的資原始檔名中加上版本號或檔案MD5值字串,如common.d5d02a02.js、common.v1.js,同時設定Cache-Control:max-age=31536000,也就是一年。在一年時間內,資原始檔如果本地有快取,就會使用快取;也就不會有304的回包。
  2. 如果資原始檔有修改,則更新檔案內容,同時修改資原始檔名,如common.v2.js,html頁面也會引用新的資原始檔名。

通過這種方式,實現了:快取檔案沒有更新,則使用快取;快取檔案有更新,則第一時間使用最新檔案的目的。即上面說的第1、2條。第3、4條由於瀏覽器內部機制,目前還無法滿足。