Android WebVIew緩存機制詳解

前言

由於H5具備 開發週期短、靈活性好 的特點,所以現在Android App大多嵌入了Android Webview組件進行Hybrid開發

但我知道你一定在煩惱Android Webview的性能問題,特別突出的是:加載速度慢 & 消耗流量

今天,我將針對Android Webview的性能問題,提出一些有效解決方案。

目錄

1.WebView的性能問題

1.1 H5頁面加載速度慢

1.1.1 渲染速度慢

1.1.2 頁面資源加載緩慢

1.2 耗費流量

2. WebView網頁緩存

2.1 瀏覽器緩存機制

2.2 Application Cache緩存機制

2.3 Dom Storage緩存機制

2.4 Database緩存機制

2.5 IndexedDB緩存機制 

2.6 File System

2.7 緩存機制彙總

3 緩存模式


1.WebView的性能問題

1.1 H5頁面加載速度慢

1.1.1 渲染速度慢

前端H5頁面渲染的速度取決於 兩個方面:

Js解析效率

Js本身的解析過程複雜、解析速度不快 & 前端頁面涉及較多JS代碼文件,所以疊加起來會導致Js解析效率非常低

手機硬件設備的性能

由於Android機型碎片化,這導致手機硬件設備的性能不可控,而大多數的Android手機硬件設備無法達到很好很好的硬件性能

總結:上述兩個原因 導致 H5頁面的渲染速度慢。

1.1.2 頁面資源加載緩慢

H5頁面一般會比較多,每加載一個H5頁面,都會產生較多網絡請求,HTML主URL自身的請求,HTML外部引用的JS、CSS、字體文件,圖片也是一個獨立的HTTP請求。

每一個請求都串行的,這麼多請求串起來,這導致H5頁面資源加載緩慢。

1.2 耗費流量

每次使用H5頁面時,用戶都需要重新加載Android WebView的H5頁面,每加載一個H5頁面,都會產生較多網絡請求(上面提到),每一個請求都串行的,這麼多請求串起來,這導致消耗的流量也會越多。

上述問題導致了Android WebView的H5頁面體驗 與 原生Native存在較大差距。

2. WebView網頁緩存

緩存,即離線存儲,這意味着H5網頁 加載後會存儲在緩存區域,在無網絡連接時也可訪問

WebView的本質 = 在Android中嵌入H5頁面,所以,Android WebView自帶的緩存機制其實就是H5頁面的緩存機制

Android WebView除了新的File System緩存機制(H5頁面新加入的緩存機制,後面會進行簡單介紹)還不支持,其他都支持。

Android WebView自帶的緩存機制有5種:

  1. 瀏覽器 緩存機制
  2. Application Cache緩存機制
  3. Dom Storage緩存機制
  4. Web SQL Database緩存機制
  5. Indexed Database緩存機制

2.1 瀏覽器緩存機制

根據HTTP協議頭裏的Cache-Control(或Expires)和Last-Modified(或Etag)等字段來控制文件緩存的機制

下面詳細介紹Cache-Control、Expires、Last-Modified&Etag四個字段

Cache-Control:用於控制文件在本地緩存有效時長

如服務器回包:Cache-Control:max-age=600,則表示文件在本地應該緩存,且有效時長是600秒(從發出請求算起)。在接下來600秒內,如果有請求這個資源,瀏覽器不會發出 HTTP 請求,而是直接使用本地緩存的文件。

Expires:與Cache-Control功能相同,即控制緩存的有效時間

Expires是HTTP1.0標準中的字段,Cache-Control 是HTTP1.1標準中新加的字段

當這兩個字段同時出現時,Cache-Control優先級較高

Last-Modified:標識文件在服務器上的最新更新時間

下次請求時,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個時間,發送給服務器,由服務器比較時間戳來判斷文件是否有修改。如果沒有修改,服務器返回304告訴瀏覽器繼續使用緩存;如果有修改,則返回200,同時返回最新的文件。

Etag:功能同Last-Modified,即標識文件在服務器上的最新更新時間。

不同的是,Etag的取值是一個對文件進行標識的特徵字串。

在向服務器查詢文件是否有更新時,瀏覽器通過If-None-Match字段把特徵字串發送給服務器,由服務器和文件最新特徵字串進行匹配,來判斷文件是否有更新:沒有更新回包304,有更新回包200

Etag和Last-Modified可根據需求使用一個或兩個同時使用。兩個同時使用時,只要滿足基中一個條件,就認爲文件沒有更新。

常見用法是:

Cache-Control與Last-Modified一起使用;

Expires與Etag一起使用;

即一個用於控制緩存有效時間,一個用於在緩存失效後,向服務查詢是否有更新

特點

優點:支持Http協議層

不足:緩存文件需要首次加載後纔會產生;瀏覽器緩存的存儲空間有限,緩存有被清除的可能;緩存的文件沒有校驗。

對於解決以上問題,可以參考手 Q 的離線包

應用場景

靜態資源文件的存儲,如` JS、CSS`、字體、圖片等。

Android Webview會將緩存的文件記錄及文件內容會存在當前 app 的 data 目錄中。

具體實現

瀏覽器緩存機制是瀏覽器內核的機制,一般都是標準的實現,即Android WebView內置自動實現。

2.2 Application Cache緩存機制

以文件爲單位進行緩存,且文件有一定更新機制(類似於瀏覽器緩存機制)

AppCache原理有兩個關鍵點:manifest 屬性和 manifest 文件。

HTML 在頭中通過 manifest 屬性引用 manifest 文件

manifest 文件:就是上面以 appcache 結尾的文件,是一個普通文件文件,列出了需要緩存的文件

瀏覽器在首次加載 HTML 文件時,會解析 manifest 屬性,並讀取 manifest 文件,獲取 Section:CACHE MANIFEST 下要緩存的文件列表,再對文件緩存

// 原理說明如下:

AppCache 在首次加載生成後,也有更新機制。被緩存的文件如果要更新,需要更新 manifest 文件

因爲瀏覽器在下次加載時,除了會默認使用緩存外,還會在後臺檢查 manifest 文件有沒有修改(byte by byte)

發現有修改,就會重新獲取 manifest 文件,對 Section:CACHE MANIFEST 下文件列表檢查更新

manifest 文件與緩存文件的檢查更新也遵守瀏覽器緩存機制

如用戶手動清了 AppCache 緩存,下次加載時,瀏覽器會重新生成緩存,也可算是一種緩存的更新

AppCache 的緩存文件,與瀏覽器的緩存文件分開存儲的,因爲 AppCache 在本地有 5MB(分 HOST)的空間限制

特點

方便構建Web App的緩存,專門爲Web App離線使用而開發的緩存機制,AppCache 是對瀏覽器緩存機制的補充。

應用場景

存儲靜態文件(如JS、CSS、字體文件)

具體實現     

   // 通過設置WebView的settings來實現
        WebSettings settings = getSettings();
        String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
        settings.setAppCachePath(cacheDirPath);
        // 1. 設置緩存路徑
        settings.setAppCacheMaxSize(20*1024*1024);
        // 2. 設置緩存大小
        settings.setAppCacheEnabled(true);
        // 3. 開啓Application Cache存儲機制

注意,每個 Application 只調用一次 WebSettings.setAppCachePath() 和WebSettings.setAppCacheMaxSize()

2.3 Dom Storage緩存機制

通過存儲字符串的Key - Value對來提供

DOM Storage分爲sessionStorage&localStorage; 二者使用方法基本相同,區別在於作用範圍不同:

a.sessionStorage:具備臨時性,即存儲與頁面相關的數據,它在頁面關閉後無法使用

b.localStorage:具備持久性,即保存的數據在頁面關閉後也可以使用。

特點

存儲空間大( 5MB):存儲空間對於不同瀏覽器不同,如Cookies 才 4KB

存儲安全、便捷:Dom Storage存儲的數據在本地,不需要經常和服務器進行交互

不像Cookies每次請求一次頁面,都會向服務器發送網絡請求

應用場景

存儲臨時、簡單的數據

代替 將 不需要讓服務器知道的信息 存儲到cookies的這種傳統方法

Dom Storage機制類似於Android的SharedPreference機制

具體實現     

// 通過設置 `WebView`的`Settings`類實現
WebSettings settings = getSettings();
// 開啓DOM storage
settings.setDomStorageEnabled(true);
        

2.4 Database緩存機制

基於 `SQL` 的數據庫存儲機制

特點

充分利用數據庫的優勢,可方便對數據進行增加、刪除、修改、查詢

應用場景

存儲適合數據庫的結構化數據

具體實現      

  // 通過設置WebView的settings實現
        WebSettings settings = getSettings();
        String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
        settings.setDatabasePath(cacheDirPath);
        // 設置緩存路徑
        settings.setDatabaseEnabled(true);
        // 開啓 數據庫存儲機制

根據官方說明,Web SQL Database存儲機制不再推薦使用(不再維護),取而代之的是IndexedDB緩存機制。

2.5 IndexedDB緩存機制 

屬於NoSQL數據庫,通過存儲字符串的Key - Value對來提供

類似於Dom Storage 存儲機制的key-value存儲方式

特點

功能強大、使用簡單,通過數據庫的事務機制進行數據操作,可對對象任何熟悉生成索引,方便查詢。

存儲空間大,默認250MB,比Dom Storage大很多。

使用靈活,以Key-Value的方式存取對象,可以使任何類型值或對象,包括二進制。

異步的API調用,避免造成等待而影響體驗。

應用場景

存儲 複雜、數據量大的結構化數據

具體實現

// 通過設置WebView的settings實現 ,只需設置支持JS就自動打開IndexedDB存儲機制,Android 在4.4開始加入對 IndexedDB 的支持,只需打開允許 JS 執行的開關就好了。

  WebSettings settings = getSettings();
  settings.setJavaScriptEnabled(true);

 

2.6 File System

爲H5頁面的數據 提供一個虛擬的文件系統

可進行文件(夾)的創建、讀、寫、刪除、遍歷等操作,就像Native App訪問本地文件系統一樣

虛擬的文件系統是運行在沙盒中

不同WebApp的虛擬文件系統是互相隔離的,虛擬文件系統與本地文件系統也是互相隔離的。

虛擬文件系統提供了兩種類型的存儲空間:臨時 & 持久性:

臨時的存儲空間:由瀏覽器自動分配,但可能被瀏覽器回收

持久性的存儲空間:需要顯式申請;自己管理(瀏覽器不會回收,也不會清除內容);存儲空間大小通過配額管理,首次申請時會一個初始的配額,配額用完需要再次申請。

特點

可存儲數據體積較大的二進制數據,可預加載資源文件,可直接編輯文件。

應用場景

通過文件系統 管理數據

具體使用

由於File System是H5新加入的緩存機制,所以Android WebView暫時不支持

2.7 緩存機制彙總

3 緩存模式

緩存模式是一種 當加載H5網頁時 該如何讀取之前保存到本地緩存

從而進行使用 的方式

即告訴Android WebView什麼時候去讀緩存,以哪種方式去讀緩存

Android WebView自帶的緩存模式有4種:

// 緩存模式說明:

      // LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據

      // LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據.

      // LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。

      // LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。

具體使用

WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章