日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android WebView 性能优化

發布時間:2025/4/16 Android 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android WebView 性能优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文出處:http://motalks.cn/2016/09/11/Android-WebView-JavaScript-3/

WebView相關閱讀

  • Android WebView 和 javaScript的互相調用(一)
  • Android WebView 和 javaScript的互相調用(二)
  • Android WebView 和 javaScript的互相調用(三)
  • Android WebView與js交互通信
  • Android 4.4 中 WebView 使用注意事項
  • Android WebView開發問題匯總
  • Android WebView 性能優化

Mo說:大家通過前兩篇文章想必都能順利的 get 到 WebView 與 JavaScript 交互的技能了。現在 App 嵌入 H5 頁面已經是稀松平常的事情了,開發者要面對 WebView 也越來越多的爆發出來,比如頁面加載慢,內存泄露,不同 Android 系統版本采用了不同內核的兼容問題等等。 所以當我們使用了 WebView 這個組件的時候,性能優化的事情就不能不提上議程了。這篇文章我們就針對上述問題來總結下 Android WebView 性能優化的常見方法。

一、頁面加載速度優化

影響頁面加載速度的因素有非常多,我們在對 WebView 加載一個網頁的過程進行調試發現,每次加載的過程中都會有較多的網絡請求,除了 web 頁面自身的 URL 請求,還會有 web 頁面外部引用的JS、CSS、字體、圖片等等都是個獨立的 http 請求。這些請求都是串行的,這些請求加上瀏覽器的解析、渲染時間就會導致 WebView 整體加載時間變長,消耗的流量也對應的真多。接下來我們就來說說幾種優化方案來是怎么解決這個問題的。

二、選擇合適的 WebView 緩存

WebView 緩存看似就是開啟幾個開關的問題,但是要弄懂這幾種緩存機制還是很有深度。下圖是騰訊某工程師總結六種 H5 常用的緩存機制的優勢及適用場景。

1、瀏覽器緩存機制:

主要前端負責,Android 端不需要進行特別的配置。

2、Dom Storage(Web Storage)存儲機制:

配合前端使用,使用時需要打開 DomStorage 開關。

WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setDomStorageEnabled(true);

3、Web SQL Database 存儲機制:

雖然已經不推薦使用了,但是為了兼容性,還是提供下 Android 端使用的方法

WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setDatabaseEnabled(true); final String dbPath = getApplicationContext().getDir("db",Context.MODE_PRIVATE).getPath(); webSettings.setDatabasePath(dbPath)

4、Application Cache 存儲機制

Application Cache(簡稱 AppCache)似乎是為支持 Web App 離線使用而開發的緩存機制。它的緩存機制類似于瀏覽器的緩存(Cache-Control 和 Last-Modified)機制,都是以文件為單位進行緩存,且文件有一定更新機制。但 AppCache 是對瀏覽器緩存機制的補充,不是替代。

不過根據官方文檔,AppCache 已經不推薦使用了,標準也不會再支持。現在主流的瀏覽器都是還支持 AppCache的,以后就不太確定了。同樣給出 Android 端啟用 AppCache 的代碼。

WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setAppCacheEnabled(true); final String cachePath = getApplicationContext().getDir("cache",Context.MODE_PRIVATE).getPath(); webSettings.setAppCachePath(cachePath); webSettings.setAppCacheMaxSize(5*1024*1024);

5、Indexed Database 存儲機制

IndexedDB 也是一種數據庫的存儲機制,但不同于已經不再支持的 Web SQL Database。IndexedDB 不是傳統的關系數據庫,可歸為 NoSQL 數據庫。IndexedDB 又類似于 Dom Storage 的 key-value 的存儲方式,但功能更強大,且存儲空間更大。

Android 在4.4開始加入對 IndexedDB 的支持,只需打開允許 JS 執行的開關就好了。

WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);

6、File System API

File System API 是 H5 新加入的存儲機制。它為 Web App 提供了一個虛擬的文件系統,就像 Native App 訪問本地文件系統一樣。由于安全性的考慮,這個虛擬文件系統有一定的限制。Web App 在虛擬的文件系統中,可以進行文件(夾)的創建、讀、寫、刪除、遍歷等操作。很可惜到目前,Android 系統的 WebView 還不支持 File System API。

簡單的介紹完了上面六種 H5 常用的緩存模式,想必大家能對 Android WebView 所支持的緩存模式有個粗略的了解。如果想和前端更好的配合使用 Android WebView 所支持的緩存,建議看下這篇文章《H5 緩存機制淺析 移動端 Web 加載性能優化》

三、常用資源預加載

上面介紹的緩存技術,能優化二次啟動 WebView 的加載速度,那首次加載 H5 頁面的速度該怎么優化呢?上面分析了一次加載過程會有許多外部依賴的 JS、CSS、圖片等資源需要下載,那我們能不能提前將這些資源下載好,等H5 加載時直接替換呢?

好在從 API 11(Android 3.0)開始,WebView 引入了 shouldInterceptRequest 函數,這個函數有兩種重載。

public WebResourceResponse shouldInterceptRequest(WebView webView, String url) //從 API 11 引入,API 21 廢棄 public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request) //從 API 21 開始引入

考慮到目前大多數 App 還要支持 API 14,所以還是使用 shouldInterceptRequest (WebView view, String url) 為例。

WebView mWebView = (WebView) findViewById(R.id.webview); mWebView.setWebViewClient(new WebViewClient() {@Overridepublic WebResourceResponse shouldInterceptRequest(WebView webView, final String url) {WebResourceResponse response = null;// 檢查該資源是否已經提前下載完成。我采用的策略是在應用啟動時,用戶在 wifi 的網絡環境下 // 提前下載 H5 頁面需要的資源。boolean resDown = JSHelper.isURLDownValid(url);if (resDown) {jsStr = JsjjJSHelper.getResInputStream(url);if (url.endsWith(".png")) {response = getWebResourceResponse(url, "image/png", ".png");} else if (url.endsWith(".gif")) {response = getWebResourceResponse(url, "image/gif", ".gif");} else if (url.endsWith(".jpg")) {response = getWebResourceResponse(url, "image/jepg", ".jpg");} else if (url.endsWith(".jepg")) {response = getWebResourceResponse(url, "image/jepg", ".jepg");} else if (url.endsWith(".js") && jsStr != null) {response = getWebResourceResponse("text/javascript", "UTF-8", ".js");} else if (url.endsWith(".css") && jsStr != null) {response = getWebResourceResponse("text/css", "UTF-8", ".css");} else if (url.endsWith(".html") && jsStr != null) {response = getWebResourceResponse("text/html", "UTF-8", ".html");}}// 若 response 返回為 null , WebView 會自行請求網絡加載資源。 return response;}});private WebResourceResponse getWebResourceResponse(String url, String mime, String style) {WebResourceResponse response = null;try {response = new WebResourceResponse(mime, "UTF-8", new FileInputStream(new File(getJSPath() + TPMD5.md5String(url) + style)));} catch (FileNotFoundException e) {e.printStackTrace();}return response;}public String getJsjjJSPath() {String splashTargetPath = JarEnv.sApplicationContext.getFilesDir().getPath() + "/JS";if (!TPFileSysUtil.isDirFileExist(splashTargetPath)) {TPFileSysUtil.createDir(splashTargetPath);}return splashTargetPath + "/";}

四、常用 JS 本地化及延遲加載

比預加載更粗暴的優化方法是直接將常用的 JS 腳本本地化,直接打包放入 apk 中。比如 H5 頁面獲取用戶信息,設置標題等通用方法,就可以直接寫入一個 JS 文件,放入 asserts 文件夾,在 WebView 調用了onPageFinished() 方法后進行加載。需要注意的是,在該 JS 文件中需要寫入一個 JS 文件載入完畢的事件,這樣前端才能接受都愛 JS 文件已經種植完畢,可以調用 JS 中的方法了。 附上一段本地化的 JS 代碼。

javascript: ; (function() {try{window.JSBridge = {'invoke': function(name) {var args = [].slice.call(arguments, 1),callback = args.pop(),params, obj = this[name];if (typeof callback !== 'function') {params = callback;callback = function() {}} else {params = args[0]} if (typeof obj !== 'object' || typeof obj.func !== 'function') {callback({'err_msg': 'system:function_not_exist'});return}obj.callback = callback;obj.params = params;obj.func(params)},'on': function(event, callback) {var obj = this['on' + event];if (typeof obj !== 'object') {callback({'err_msg': 'system:function_not_exist'});retrun}if (typeof callback !== 'undefined') obj.callback = callback},'login': {'func': function(params) {prompt("login", JSON.stringify(params))},'params': {},'callback': function(res) {}},'settitle': {'func': function(params) {prompt("settitle",JSON.stringify(params))},'params': {},'callback': function(res) {}},}catch(e){alert('demo.js error:'+e);}var readyEvent = document.createEvent('Events');readyEvent.initEvent('JSBridgeReady', true, true);document.dispatchEvent(readyEvent) })();

六、關于 JS 延遲加載

Android 的 OnPageFinished 事件會在 Javascript 腳本執行完成之后才會觸發。如果在頁面中使 用JQuery,會在處理完 DOM 對象,執行完 $(document).ready(function() {}); 事件自會后才會渲染并顯示頁面。而同樣的頁面在 iPhone 上卻是載入相當的快,因為 iPhone 是顯示完頁面才會觸發腳本的執行。所以我們這邊的解決方案延遲 JS 腳本的載入,這個方面的問題是需要Web前端工程師幫忙優化的。

七、使用第三方 WebView 內核

WebView 的兼容性一直也是困擾我們 Android 開發者的一個大問題,不說 Android 4.4 版本 Google 使用了Chromium 替代 Webkit 作為 WebView 內核,就看看國內眾多的第三方 ROM 都有可能會對原生的 WebView 做出修改,這時候如果出現兼容問題,是非常難定位到問題和解決的。

在一次使用微信瀏覽訂閱公眾號文章的過程中,發現微信的 H5 頁面有一行 『QQ 瀏覽器 X5 內核提供技術支持』。順著這個線索我就找到了騰訊瀏覽服務。發現騰訊已經把這個功能開放了,而且集成的 SDK 很小只有212 KB。這是很驚人的,通過介紹才發現這個 SDK 是可以共享微信和手機 QQ 的 X5 內核。這就很方便了,作為國內市場最不可或缺的兩個 App,我們能只需要集成一個很小的 SDK 就可以共享使用 X5 內核了,不得不說騰訊還是很有想法的。

簡單摘錄些功能亮點,想必能讓大家高潮一番。詳細內容大家可以直接到騰訊瀏覽服務看看,我相信不會讓你們失望的。

網頁瀏覽能力

  • Web頁面crash率降低75%
  • 頁面打開速度提升35%
  • 流量節省60%

閱讀模式

  • 去除網頁中廣告等雜質
  • 優化文章的閱讀體驗

文件打開能力

  • 包括會話頁的互傳文件及郵件中附件
  • 支持doc、ppt、xls、pdf等辦公格式
  • 支持jpg、gif、png、bmp等圖片格式
  • 支持zip、rar等壓縮文件
  • 支持mp3、mp4、RMVB等音視頻格式

視頻菜單能力

  • 支持屏幕調節等常規視頻菜單功能
  • 靈活切換全屏&小窗功能

八、WebView 導致的內存泄露

Android 中的 WebView 存在很大的兼容性問題,不僅僅是 Android 系統版本的不同對 WebView 產生很大的差異,另外不同的廠商出貨的 ROM 里面 WebView 也存在著很大的差異。更嚴重的是標準的 WebView 存在內存泄露的問題,看這里WebView causes memory leak - leaks the parent Activity。所以通常根治這個問題的辦法是為 WebView 開啟另外一個進程,通過 AIDL 與主進程進行通信,WebView 所在的進程可以根據業務的需要選擇合適的時機進行銷毀,從而達到內存的完整釋放。

這段話來自胡凱翻譯的 Google Android 內存優化之 OOM 。這里提到的讓 WebView 獨立運行在一個進程里,用完 WebView 后直接銷毀這個進程,即使內存泄露了,也不會影響到主進程。微信,手 Q 等 App 也采用了這個方案。但是這就涉及到了跨進程通訊,處理起來就比較麻煩。

另外個解決方案,就是使用自己封裝的 WebView,比如上面提到的 X5 內核,且使用 WebView 的時候,不在 XML 里面聲明,而是在代碼中直接 new 出來,傳入 application context 來防止 activity 引用被濫用。

WebView webView = new WebView(getContext().getApplicationContext()); webFrameLayout.addView(webView, 0);

在使用了這個方式后,基本上 90% 的 WebView 內存泄漏的問題便得以解決。

上面兩個方案,大家可以結合自己的項目情況選擇。另外對 WebView 內存泄露原因感興趣的可以看看這篇文章。

《Android中導致內存泄漏的竟然是它—-Dialog》

參考文章

《H5 緩存機制淺析 移動端 Web 加載性能優化》

《android內存優化之webview》

總結

以上是生活随笔為你收集整理的Android WebView 性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久久久久麻豆 | 国产精品七区 | 成年人免费网站在线观看 | 国产成人精品亚洲精品色欲 | 一本色道久久综合无码人妻 | 天天插天天摸 | 自拍偷拍欧美日韩 | 亚洲一区二区在线 | 亚洲av片一区二区三区 | 国产精品九九九 | 欧美 日韩 国产一区 | 就操成人网| 奇米影视狠狠干 | 国产一区二区片 | 在线免费观看黄色小视频 | 国产成年无码久久久久毛片 | 精东av在线 | 九九精品视频在线观看 | 久久精品这里 | 男人的天堂一级片 | 在线国产视频 | 国产欧美一区二区 | 五月婷婷小说 | 亚洲乱论| 黑人巨大精品欧美一区二区免费 | 日韩欧美高清一区 | 热久久精品免费视频 | 骚黄网站| 自拍视频网站 | 亚洲人成在线播放 | 国产精彩视频在线观看 | 夜福利视频 | 中文字幕在线观看日韩 | 99久久精品日本一区二区免费 | 久久94 | 日本少妇高潮抽搐 | av一级大片| 人人澡人人看 | 亚洲区小说区图片区qvod | 国产女人叫床高潮大片免费 | 农村村妇真实偷人视频 | 99爱精品 | 国产嫩草视频 | 日韩夫妻性生活 | 国产在线视频福利 | 在线观看视频一区 | 91丝袜一区在线观看 | 麻豆社 | 99精品国产成人一区二区 | 男女搞网站 | 制服丝袜av在线播放 | 黄色片网站视频 | 国产精品人成 | 中国女人一级一次看片 | 久草老司机 | 美女国产精品 | 你懂的亚洲 | 一卡二卡国产 | 欧美日韩在线免费观看视频 | 小少妇哺乳喂奶播放 | 国产自偷| 中文字幕日韩精品在线观看 | 黄a毛片| 色肉色伦交av色肉色伦 | 99久热在线精品996热是什么 | 在线观看免费视频一区二区 | 亚洲综合五月 | 欧美精品在线播放 | 久久亚洲国产成人精品性色 | 阿v视频在线免费观看 | 免费在线观看av网址 | 九月色婷婷 | 国产黑丝一区二区 | 亚州欧美日韩 | 青青精品 | 日韩精美视频 | 丰满的女邻居 | 69精品一区二区 | 一本大道综合伊人精品热热 | 成人做爰66片免费看网站 | 99er这里只有精品 | 天堂成人 | 91久久婷婷 | 欧美色图狠狠干 | 农村老女人av | 黄色高清网站 | 激情五月视频 | 激情五月综合色婷婷一区二区 | 亚州欧美在线 | 91成人免费看片 | 韩国日本美国免费毛片 | 日韩一区二区三区视频 | 亚洲欧美日韩久久精品 | 亚洲国产成人在线视频 | 3d动漫啪啪精品一区二区中文字幕 | 亚洲videos| a级片在线看 | 精人妻无码一区二区三区 | 色综合a|