android webView的緩存機制和資源預加載

android 原生使用WebView嵌入H5頁面 Hybrid開發

一、性能問題

  • android webview 里H5加載速度慢
  • 網絡流量大
1、H5頁面加載速度慢
  1. 渲染速度慢

    js解析效率

    js本身的解析過程復雜、解析速度不快,前端頁面設計較多的js代碼文件

    手機硬件設備的性能

    機型多,硬件性能不一

  2. 資源加載慢

    H5頁面的資源多

    網絡請求數量多

    ? H5頁面所有資源都需要從網絡請求

二、解決方案

  • 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,則表示文件在本地應該緩存,且有效時長是600秒(從發出請求算起)。在接下來600秒內,如果有請求這個資源,瀏覽器不會發出 HTTP 請求,而是直接使用本地緩存的文件。

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

    ? cache-Control 優先級高

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

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

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

優點:支持Http協議層

缺點:緩存文件需要首次加載后才會產生;瀏覽器緩存的存儲空間有限,緩存有被清楚的可能,緩存的文件沒有校驗

可以緩存講臺文件資源,如JS,CSS、文本、圖片等,webView 會將緩存的文件記錄及文件內容會存在當前appde data目錄中,

Application Cache 緩存機制

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

AppCache : manifest 屬性和manifest文件

<!DOCTYPE html>
<html manifest="demo_html.appcache">
// HTML 在頭中通過 manifest 屬性引用 manifest 文件
// manifest 文件:就是上面以 appcache 結尾的文件,是一個普通文件文件,列出了需要緩存的文件
// 瀏覽器在首次加載 HTML 文件時,會解析 manifest 屬性,并讀取 manifest 文件,獲取 Section:CACHE MANIFEST 下要緩存的文件列表,再對文件緩存
<body>
...
</body>
</html>

// 原理說明如下:
AppCache 在首次加載生成后,也有更新機制。被緩存的文件如果要更新,需要更新 manifest 文件
因為瀏覽器在下次加載時,除了會默認使用緩存外,還會在后臺檢查 manifest 文件有沒有修改(byte by byte)
發現有修改,就會重新獲取 manifest 文件,對 Section:CACHE MANIFEST 下文件列表檢查更新
manifest 文件與緩存文件的檢查更新也遵守瀏覽器緩存機制
如用戶手動清了 AppCache 緩存,下次加載時,瀏覽器會重新生成緩存,也可算是一種緩存的更新
AppCache 的緩存文件,與瀏覽器的緩存文件分開存儲的,因為 AppCache 在本地有 5MB(分 HOST)的空間限制

    // 通過設置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()

Dom Storage 緩存機制

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

sessionStorage:具備臨時性,即存儲與頁面相關的數據,它在頁面關閉后無法使用
localStorage:具備持久性,即保存的數據在頁面關閉后也可以使用。

特點:

  • 存儲空間大(5MB): 存儲空間對于不同瀏覽器不同,如Cookies才4KB
  • 存儲安全、便捷:Dom Storage 存儲的數據在本地,不需要經常和服務器進行交互。

應用:

? 存儲臨時、簡單的數據

? 類似于sharedPreference機制

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

Web SQL Database 緩存機制

? 基于SQL的數據庫存儲機制

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

應用:

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

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

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

IndexedDB緩存機制

屬于NoSQL數據庫,通過存儲字符串的Key-Value對來提供,類似于Dom Storage 存儲機制的key-value存儲方式

優點:

  • 功能強大、使用簡單

    通過數據庫的事務(tranction)機制進行數據操作

    可對對象任何屬性生成索引,方便查詢

  • 存儲空間大

    較大的存儲空間,默認推薦250MB(分HOST)

  • 使用靈活

    以key-value的方式存存取對象,可以是任何類型值或對象,包括二級制

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

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

// 通過設置WebView的settings實現
WebSettings settings = getSettings();

    settings.setJavaScriptEnabled(true);// 只需設置支持JS就自動打開IndexedDB存儲機制// Android 在4.4開始加入對 IndexedDB 的支持,只需打開允許 JS 執行的開關就好了。

資源預加載

? 提前加載將使用的H5頁面,即提前構建緩存

? 預加載webView 、預加載H5資源

預加載WebView對象

? 提前初始化一個webView對象,后續復用這個webView對象

預加載H5資源

  1. 在應用啟動、初始化第一個WebView對象時,直接開始網絡請求加載H5頁面
  2. 后續需打開這些H5頁面時就直接從該本地對象中獲取

自身構建緩存

為了有效解決 Android WebView 的性能問題,除了使用 Android WebView 自身的緩存機制,還可以自己針對某一需求場景構建緩存機制。

實現方法:

  1. 事先將更新頻率較低、常用 & 固定的H5靜態資源 文件(如JSCSS文件、圖片等) 放到本地
  2. 攔截H5頁面的資源網絡請求 并進行檢測
  3. 如果檢測到本地具有相同的靜態資源 就 直接從本地讀取進行替換 而 不發送該資源的網絡請求 到 服務器獲取

實現方法:

假設現在需要攔截一個圖片的資源并用本地資源進行替代

    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")) {// 假設網頁里該圖片資源的地址為:http://abc.com/imgage/logo.gif// 圖片的資源文件名為:logo.gifInputStream is = null;// 步驟2:創建一個輸入流try {is =getApplicationContext().getAssets().open("images/abc.png");// 步驟3:獲得需要替換的資源(存放在assets文件夾里)// a. 先在app/src/main下創建一個assets文件夾// b. 在assets文件夾里再創建一個images文件夾// c. 在images文件夾放上需要替換的資源(此處替換的是abc.png圖片)} catch (IOException e) {e.printStackTrace();}// 步驟4:替換資源WebResourceResponse response = new WebResourceResponse("image/png","utf-8", is);// 參數1:http請求里該圖片的Content-Type,此處圖片為image/png// 參數2:編碼類型// 參數3:存放著替換資源的輸入流(上面創建的那個)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")) {// 假設網頁里該圖片資源的地址為:http://abc.com/imgage/logo.gif// 圖片的資源文件名為:logo.gifInputStream is = null;// 步驟2:創建一個輸入流try {is = getApplicationContext().getAssets().open("images/abc.png");// 步驟3:獲得需要替換的資源(存放在assets文件夾里)// a. 先在app/src/main下創建一個assets文件夾// b. 在assets文件夾里再創建一個images文件夾// c. 在images文件夾放上需要替換的資源(此處替換的是abc.png圖片} catch (IOException e) {e.printStackTrace();}// 步驟4:替換資源WebResourceResponse response = new WebResourceResponse("image/png","utf-8", is);// 參數1:http請求里該圖片的Content-Type,此處圖片為image/png// 參數2:編碼類型// 參數3:存放著替換資源的輸入流(上面創建的那個)return response;}return super.shouldInterceptRequest(view, request);}
});
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388899.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388899.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388899.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql springboot 緩存_Spring Boot 整合 Redis 實現緩存操作

摘要: 原創出處 www.bysocket.com 「泥瓦匠BYSocket 」歡迎轉載&#xff0c;保留摘要&#xff0c;謝謝&#xff01;『 產品沒有價值&#xff0c;開發團隊再優秀也無濟于事 – 《啟示錄》 』本文提綱一、緩存的應用場景二、更新緩存的策略三、運行 springboot-mybatis-redis 工程…

http壓力測試工具及使用說明

http壓力測試工具及使用說明 轉 說明&#xff1a;介紹幾款簡單、易使用http壓測工具&#xff0c;便于研發同學&#xff0c;壓測服務&#xff0c;明確服務臨界值&#xff0c;尋找服務瓶頸點。 壓測時候可重點以下指標&#xff0c;關注并發用戶數、TPS&#xff08;每秒事務數量&a…

itchat 道歉_人類的“道歉”

itchat 道歉When cookies were the progeny of “magic cookies”, they were seemingly innocuous packets of e-commerce data that stored a user’s partial transaction state on their computer. It wasn’t disclosed that you were playing a beneficial part in a muc…

使用Kubespray部署生產可用的Kubernetes集群(1.11.2)

Kubernetes的安裝部署是難中之難&#xff0c;每個版本安裝方式都略有區別。筆者一直想找一種支持多平臺 、相對簡單 、適用于生產環境 的部署方案。經過一段時間的調研&#xff0c;有如下幾種解決方案進入筆者視野&#xff1a; 部署方案優點缺點Kubeadm官方出品部署較麻煩、不夠…

android webView 與 JS交互方式

webView 與JS交互 Android調用JS代碼的方法有&#xff1a; 通過WebView的loadUrl&#xff08;&#xff09;通過WebView的evaluateJavascript&#xff08;&#xff09; 對于JS調用Android代碼的方法有3種&#xff1a; 通過WebView的addJavascriptInterface&#xff08;&…

matlab軟件imag函數_「復變函數與積分變換」基本計算代碼

使用了Matlab代碼&#xff0c;化簡平時遇到的計算問題&#xff0c;也可以用于驗算結果來自211工科專業2學分復變函數與積分變換課程求復角主值sym(angle(待求復數))%公式 sym(angle(1sqrt(3)*i))%舉例代入化簡將 代入關于z的函數f(z)中并化解&#xff0c;用于公式法計算無窮遠點…

數據科學 python_為什么需要以數據科學家的身份學習Python的7大理由

數據科學 pythonAs a new Data Scientist, you know that your path begins with programming languages you need to learn. Among all languages that you can select from Python is the most popular language for all Data Scientists. In this article, I will cover 7 r…

[luoguP4142]洞穴遇險

https://www.zybuluo.com/ysner/note/1240792 題面 戳我 解析 這種用來拼接的奇形怪狀的東西&#xff0c;要不就是輪廓線\(DP\)&#xff0c;要不就是網絡流。 為了表示奇數點&#xff08;即\((xy)\%21\)&#xff09;的危險值&#xff0c;把該點拆為兩個點&#xff0c;連一條邊長…

飛信虛擬機

做完了一個圖片處理軟件,突然想到上次上網看到C#程序脫離.NET FRAMEWORK運行的文章,于是決定自己動手試一下。 之前看到有用別的方法來實現的&#xff0c;但我還是選擇了現在比較流行的軟件飛信中帶的VMDotNet&#xff0c;也就是所謂的.NET FRAMEWORK虛擬機吧。相信有很多人也已…

django的contenttype表

https://blog.csdn.net/aaronthon/article/details/81714496 這篇文章已經非常詳細了,供自己以后忘了...回看...... 總結&#xff1a; 當一張表和多個表FK關聯&#xff0c;并且多個FK中只能選擇其中一個或其中n個時&#xff0c;可以利用contenttype&#xff0c;固定用三個字段…

視頻播放問題和提高性能方案

1.Five symptoms of poor video performance 1.1 視頻加載緩慢 ?Perceived Wait Time Time to first frame (TTFF): ? 播放開始所需的adaptive bitrate(ABR)流媒體段的數量。(我們稍后將對此進行更詳細的討論。) ? 視頻請求發送到視頻加載之間的時間(即接收到足夠的數據…

rabbitmq 不同的消費者消費同一個隊列_RabbitMQ 消費端限流、TTL、死信隊列

消費端限流1. 為什么要對消費端限流假設一個場景&#xff0c;首先&#xff0c;我們 Rabbitmq 服務器積壓了有上萬條未處理的消息&#xff0c;我們隨便打開一個消費者客戶端&#xff0c;會出現這樣情況: 巨量的消息瞬間全部推送過來&#xff0c;但是我們單個客戶端無法同時處理這…

動量策略 python_在Python中使用動量通道進行交易

動量策略 pythonMost traders use Bollinger Bands. However, price is not normally distributed. That’s why only 42% of prices will close within one standard deviation. Please go ahead and read this article. However, I have some good news.大多數交易者使用布林…

css3 變換、過渡效果、動畫

1 CSS3 選擇器 1.1 基本選擇器 1.2 層級 空格 > .itemli ~ .item~p 1.3 屬性選擇器 [attr] [attrvalue] [attr^value] [attr$value] [attr*value] [][][] 1.4 偽類選擇器 :link :visited :hover :active :focus :first-child .list li:first-child :last-chi…

webservice 啟用代理服務器

您會發現你寫完了一個webservice在調用的時候發現怎也沒辦法調用&#xff0c;一個簡單的webservice怎么不能使用&#xff0c;一肚子的怨恨&#xff0c;哈哈您可能沒有為webservice設置代理。 下面就給您寫個調用的用例和大家分享下。其實很簡單&#xff0c;但是你沒有想到的時…

mysql常用的存儲引擎_Mysql存儲引擎

什么是存儲引擎&#xff1f;關系數據庫表是用于存儲和組織信息的數據結構&#xff0c;可以將表理解為由行和列組成的表格&#xff0c;類似于Excel的電子表格的形式。有的表簡單&#xff0c;有的表復雜&#xff0c;有的表根本不用來存儲任何長期的數據&#xff0c;有的表讀取時非…

android studio設計模式和文本模式切換

轉載于:https://www.cnblogs.com/judes/p/9437104.html

高斯模糊為什么叫高斯濾波_為什么高斯是所有發行之王?

高斯模糊為什么叫高斯濾波高斯分布及其主要特征&#xff1a; (Gaussian Distribution and its key characteristics:) Gaussian distribution is a continuous probability distribution with symmetrical sides around its center. 高斯分布是連續概率分布&#xff0c;其中心周…

C# webbrowser 代理

百度&#xff0c;google加自己理解后&#xff0c;將所得方法總結一下&#xff1a; 方法1&#xff1a;修改注冊表Software//Microsoft//Windows//CurrentVersion//Internet Settings下 ProxyEnable和ProxyServer。這種方法適用于局域網用戶&#xff0c;撥號用戶無效。 1p…

C MySQL讀寫分離連接串_Mysql讀寫分離

一 什么是讀寫分離MySQL Proxy最強大的一項功能是實現“讀寫分離(Read/Write Splitting)”。基本的原理是讓主數據庫處理事務性查詢&#xff0c;而從數據庫處理SELECT查詢。數據庫復制被用來把事務性查詢導致的變更同步到集群中的從數據庫。當然&#xff0c;主服務器也可以提供…