android webView的缓存机制和资源预加载
android 原生使用WebView嵌入H5頁面 Hybrid開發(fā)
一、性能問題
- android webview 里H5加載速度慢
- 網(wǎng)絡(luò)流量大
1、H5頁面加載速度慢
渲染速度慢
js解析效率
js本身的解析過程復雜、解析速度不快,前端頁面設(shè)計較多的js代碼文件
手機硬件設(shè)備的性能
機型多,硬件性能不一
資源加載慢
H5頁面的資源多
網(wǎng)絡(luò)請求數(shù)量多
? H5頁面所有資源都需要從網(wǎng)絡(luò)請求
二、解決方案
- webView組件本身的緩存機制
- 資源預加載
- 資源攔截
webView組件本身的緩存機制
-
WebView自帶的緩存機制有5種:瀏覽器 緩存機制
-
Application Cache 緩存機制
-
Dom Storage 緩存機制
-
Web SQL Database 緩存機制
-
Indexed Database 緩存機制
-
File System 緩存機制(H5頁面新加入的緩存機制,雖然Android WebView暫時不支持,但會進行簡單介紹)
(1) Cache-Control: 用于控制文件在本地緩存的有效時長
? eg:Cache-Control:max-age=600,則表示文件在本地應(yīng)該緩存,且有效時長是600秒(從發(fā)出請求算起)。在接下來600秒內(nèi),如果有請求這個資源,瀏覽器不會發(fā)出 HTTP 請求,而是直接使用本地緩存的文件。
(2)Expires: 與Cache-Control 功能相同,即控制緩存的有效時間
? cache-Control 優(yōu)先級高
(3) Last-Modified: 標識文件在服務(wù)器上的最新更新時間
? 下次請求時,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個時間,發(fā)送給服務(wù)器,由服務(wù)器比較時間戳來判斷文件是否有修改。如果沒有修改,服務(wù)器返回304告訴瀏覽器繼續(xù)使用緩存;如果有修改,則返回200,同時返回最新的文件。
(4) Etag:功能同Last-Modified, 即標識文件在服務(wù)器上的最新更新時間
優(yōu)點:支持Http協(xié)議層
缺點:緩存文件需要首次加載后才會產(chǎn)生;瀏覽器緩存的存儲空間有限,緩存有被清楚的可能,緩存的文件沒有校驗
可以緩存講臺文件資源,如JS,CSS、文本、圖片等,webView 會將緩存的文件記錄及文件內(nèi)容會存在當前appde data目錄中,
Application Cache 緩存機制
以文件為單位進行緩存,且文件有一定更新機制(類似于瀏覽器緩存機制)
AppCache : manifest 屬性和manifest文件
<!DOCTYPE html> <html manifest="demo_html.appcache"> // HTML 在頭中通過 manifest 屬性引用 manifest 文件 // manifest 文件:就是上面以 appcache 結(jié)尾的文件,是一個普通文件文件,列出了需要緩存的文件 // 瀏覽器在首次加載 HTML 文件時,會解析 manifest 屬性,并讀取 manifest 文件,獲取 Section:CACHE MANIFEST 下要緩存的文件列表,再對文件緩存 <body> ... </body> </html>// 原理說明如下:
AppCache 在首次加載生成后,也有更新機制。被緩存的文件如果要更新,需要更新 manifest 文件
因為瀏覽器在下次加載時,除了會默認使用緩存外,還會在后臺檢查 manifest 文件有沒有修改(byte by byte)
發(fā)現(xiàn)有修改,就會重新獲取 manifest 文件,對 Section:CACHE MANIFEST 下文件列表檢查更新
manifest 文件與緩存文件的檢查更新也遵守瀏覽器緩存機制
如用戶手動清了 AppCache 緩存,下次加載時,瀏覽器會重新生成緩存,也可算是一種緩存的更新
AppCache 的緩存文件,與瀏覽器的緩存文件分開存儲的,因為 AppCache 在本地有 5MB(分 HOST)的空間限制
Application 只調(diào)用一次 WebSettings.setAppCachePath() 和
WebSettings.setAppCacheMaxSize()
Dom Storage 緩存機制
通過存儲字符串的Key-Value 對來提供
sessionStorage:具備臨時性,即存儲與頁面相關(guān)的數(shù)據(jù),它在頁面關(guān)閉后無法使用
localStorage:具備持久性,即保存的數(shù)據(jù)在頁面關(guān)閉后也可以使用。
特點:
- 存儲空間大(5MB): 存儲空間對于不同瀏覽器不同,如Cookies才4KB
- 存儲安全、便捷:Dom Storage 存儲的數(shù)據(jù)在本地,不需要經(jīng)常和服務(wù)器進行交互。
應(yīng)用:
? 存儲臨時、簡單的數(shù)據(jù)
? 類似于sharedPreference機制
// 通過設(shè)置 `WebView`的`Settings`類實現(xiàn)WebSettings settings = getSettings();settings.setDomStorageEnabled(true);// 開啟DOM storageWeb SQL Database 緩存機制
? 基于SQL的數(shù)據(jù)庫存儲機制
? 充分利用數(shù)據(jù)庫的優(yōu)勢,可方便對數(shù)據(jù)進行增加、刪除、修改、查詢。
應(yīng)用:
? 存儲適合數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)
// 通過設(shè)置WebView的settings實現(xiàn)WebSettings settings = getSettings();String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";settings.setDatabasePath(cacheDirPath);// 設(shè)置緩存路徑settings.setDatabaseEnabled(true);// 開啟 數(shù)據(jù)庫存儲機制官方說明,Web SQL Database 存儲機制不在推薦使用(不在維護),取而代之的是IndexedDB緩存機制。
IndexedDB緩存機制
屬于NoSQL數(shù)據(jù)庫,通過存儲字符串的Key-Value對來提供,類似于Dom Storage 存儲機制的key-value存儲方式
優(yōu)點:
-
功能強大、使用簡單
通過數(shù)據(jù)庫的事務(wù)(tranction)機制進行數(shù)據(jù)操作
可對對象任何屬性生成索引,方便查詢
-
存儲空間大
較大的存儲空間,默認推薦250MB(分HOST)
-
使用靈活
以key-value的方式存存取對象,可以是任何類型值或?qū)ο?#xff0c;包括二級制
異步的API調(diào)用,避免造成等待而影響體驗
存儲 復雜、數(shù)據(jù)量大的結(jié)構(gòu)化數(shù)據(jù)
// 通過設(shè)置WebView的settings實現(xiàn)
WebSettings settings = getSettings();
資源預加載
? 提前加載將使用的H5頁面,即提前構(gòu)建緩存
? 預加載webView 、預加載H5資源
預加載WebView對象
? 提前初始化一個webView對象,后續(xù)復用這個webView對象
預加載H5資源
自身構(gòu)建緩存
為了有效解決 Android WebView 的性能問題,除了使用 Android WebView 自身的緩存機制,還可以自己針對某一需求場景構(gòu)建緩存機制。
實現(xiàn)方法:
實現(xiàn)方法:
假設(shè)現(xiàn)在需要攔截一個圖片的資源并用本地資源進行替代
mWebview.setWebViewClient(new WebViewClient() {// 重寫 WebViewClient 的 shouldInterceptRequest ()// API 21 以下用shouldInterceptRequest(WebView view, String url)// API 21 以上用shouldInterceptRequest(WebView view, WebResourceRequest request)// 下面會詳細說明// API 21 以下用shouldInterceptRequest(WebView view, String url)@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, String url) {// 步驟1:判斷攔截資源的條件,即判斷url里的圖片資源的文件名if (url.contains("logo.gif")) {// 假設(shè)網(wǎng)頁里該圖片資源的地址為:http://abc.com/imgage/logo.gif// 圖片的資源文件名為:logo.gifInputStream is = null;// 步驟2:創(chuàng)建一個輸入流try {is =getApplicationContext().getAssets().open("images/abc.png");// 步驟3:獲得需要替換的資源(存放在assets文件夾里)// a. 先在app/src/main下創(chuàng)建一個assets文件夾// b. 在assets文件夾里再創(chuàng)建一個images文件夾// c. 在images文件夾放上需要替換的資源(此處替換的是abc.png圖片)} catch (IOException e) {e.printStackTrace();}// 步驟4:替換資源WebResourceResponse response = new WebResourceResponse("image/png","utf-8", is);// 參數(shù)1:http請求里該圖片的Content-Type,此處圖片為image/png// 參數(shù)2:編碼類型// 參數(shù)3:存放著替換資源的輸入流(上面創(chuàng)建的那個)return response;}return super.shouldInterceptRequest(view, url);}?
// API 21 以上用shouldInterceptRequest(WebView view, WebResourceRequest request)@TargetApi(Build.VERSION_CODES.LOLLIPOP)@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {// 步驟1:判斷攔截資源的條件,即判斷url里的圖片資源的文件名if (request.getUrl().toString().contains("logo.gif")) {// 假設(shè)網(wǎng)頁里該圖片資源的地址為:http://abc.com/imgage/logo.gif// 圖片的資源文件名為:logo.gifInputStream is = null;// 步驟2:創(chuàng)建一個輸入流try {is = getApplicationContext().getAssets().open("images/abc.png");// 步驟3:獲得需要替換的資源(存放在assets文件夾里)// a. 先在app/src/main下創(chuàng)建一個assets文件夾// b. 在assets文件夾里再創(chuàng)建一個images文件夾// c. 在images文件夾放上需要替換的資源(此處替換的是abc.png圖片} catch (IOException e) {e.printStackTrace();}// 步驟4:替換資源WebResourceResponse response = new WebResourceResponse("image/png","utf-8", is);// 參數(shù)1:http請求里該圖片的Content-Type,此處圖片為image/png// 參數(shù)2:編碼類型// 參數(shù)3:存放著替換資源的輸入流(上面創(chuàng)建的那個)return response;}return super.shouldInterceptRequest(view, request);} }); } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的android webView的缓存机制和资源预加载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到死人墓地有什么说法
- 下一篇: 孕妇做梦梦到鲫鱼是什么意思