當WebView的使用頻率變得頻繁的時候,對於其各方面的優化就變得逐漸重要了起來。能夠知道的是,咱們每加載一個 H5頁面,都會有不少的請求。除了HTML主URL自身的請求外,HTML外部引用的 JS、CSS、字體文件、圖片都是一個個獨立的HTTP 請求,雖然請求是併發的,但當網頁總體數量達到必定程度的時候,再加上瀏覽器解析、渲染的時間,Web總體的加載時間變得很長。同時請求文件越多,消耗的流量也會越多。那麼對於加載的優化就變得很是重要,這方面的經驗我也沒有什麼別的,大概三個方面:
一個,就是資源本地化的問題
首先能夠明確的是,以目前的網絡條件,經過網絡去服務器獲取資源的速度是遠遠比不上從本地讀取的。談論各類優化策略其實偏偏忽略了「須要加載」纔是阻擋速度提高的最大絆腳石。因此咱們的思路一,就是將一些較重的資源好比js、css、圖片甚至HTML自己進行本地化處理,在每次加載到這些資源的時候,從本地讀取進行加載,能夠簡單記憶爲「存·取·更」。
1.「存」——將上述重量級資源打包進apk文件,每次加載相應文件時時從本地取便可。也可不打包,在第一次加載時以及接下來的若干間隔時間裏動態下載存儲,將全部的資源文件都存在Android的asset目錄下;
2.「取」——重寫WebViewClient的WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)方法,經過必定的判別方法(例如正則表達式)攔截相應的請求,從本地讀取相應資源並返回;
3.「更」——創建起Cache Control機制,按期或使用API通知的形式控制本地資源的更新,保證本地資源是最新和可用的。
第二個,就是緩存的問題
假若你不採用或不徹底採用第一條資源本地化的思路,那麼你的WebView緩存是必需要開啓的(雖然這一思路和第一條有重合的地方)。
WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//開啓DOM緩存
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
在網絡正常時,採用默認緩存策略,在緩存可獲取而且沒有過時的狀況下加載緩存,不然經過網絡獲取資源以減小頁面的網絡請求次數。
這裏值得提起的是,咱們常常在app裏用WebView展現頁面時,並不想讓用戶以爲他是在訪問一個網頁。由於假若咱們的app裏網頁很是多,而咱們給用戶的感受又都像在訪問網頁的話,咱們的app便失去了意義。(個人意思是爲何用戶不直接使用瀏覽器呢?)
因此這時,離線緩存的問題就值得咱們注意。咱們須要讓用戶在沒有網的時候,依然可以操做咱們的app,而不是面對一個和瀏覽器裏的網絡錯誤同樣的頁面,哪怕他能進行的操做十分有限。
這裏個人思路是,在開啓緩存的前提下,WebView在加載頁面時檢測網絡變化,假若在加載頁面時用戶的網絡忽然斷掉,咱們應當更改WebView的緩存策略。
ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo.isAvailable()) {
settings.setCacheMode(WebSettings.LOAD_DEFAULT);//網絡正常時使用默認緩存策略
} else {
settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//網絡不可用時只使用緩存
}
既然有緩存,就要有緩存控制,與一類似的是咱們也要創建緩存控制機制,按期或接受服務器通知來進行緩存的清空或更新。
第三個,就是延遲加載和執行js
在WebView中,onPageFinished()的回調意味着頁面加載的完成。但該方法會在JavScript腳本執行完成後纔會觸發,假若咱們要加載的頁面使用了JQuery,會在處理完DOM對象,執行完$(document).ready(function() {})後纔會渲染並顯示頁面。這是不可接受的,因此咱們須要對Js進行延遲加載,固然這部分是Web前端的工做。css