android h5使用缓存_android性能优化(三)之Webview优化

本文深入探讨了Webview在Android应用中的性能问题及其优化方法,包括Webview提前初始化以减少加载时间,本地缓存H5页面资源,通过webpack+gzip和CDN加速拉取,以及H5动态数据的并行拉取策略,旨在提升用户体验和减少页面加载延迟。
摘要由CSDN通过智能技术生成

阅读本文大概需要 4 分钟。
这篇把Webview的优化单独拎出来,是因为Webview与其他普通view来说有自身独特的特点。
在做一些native+H5应用开发时,Webview的性能问题一直是关注的重点。所谓Webview性能问题,就是从打开Webview页面开始到可以和用户交互,这期间花费的时间相对于原生页面来说过长,从直观上来讲,用户等待的时间变长了!
而用户的耐心是有限的,如果几秒钟之内页面仍是白屏,很有可能就会关闭此页面,那么页面功能再酷炫,再强大也没用。而通常情况下,公司的活动页往往都用H5来实现,因此如果页面展现速度过慢的话,还会造成公司损失。
因此,做好Webview优化是很有必要的。

一. 分析
为什么拥有Webview的H5页面打开这么慢,是因为它通常会经历以下几个阶段:
1)Webview初始化。2)到达新的页面,网络连接,从服务器下载html,css,js,页面白屏。3)页面基本框架出现,js请求页面数据,页面处于loading状态。4)出现所需的数据,完成整个页面的渲染,用户可交互。
可以用下面这张图来表示:

48705dda4e45eb42330e33646a73dcc7.png

很明显,相对于原生应用只需要从后台拉取数据进行渲染来说,Webview多了初始化,拉取整个页面资源这2个步骤,而且他们的顺序是串行的。
即必须在完成初始化后才能开始建立网络连接(因为Webview相当于浏览器客户端,我们在PC上也是必须先打开chrome浏览器才能再输入网址打开页面),拉取html,css,js等资源,而只有拉取到js之后,js才能发起ajax网络请求,获取需要展现的动态数据。
而初始化,建立网络连接,拉取数据恰恰都是比较耗时的操作,这就是为什么我们从直观上来讲感觉速度太慢的原因。
知道了原因后,我们就可以针对各个阶段来逐个优化。

二. Webview提前初始化
我们知道每个页面在打开时都会调用setContentView()方法 -> inflate() -> createViewFromTag(),也就是说都会调用view的构造函数,webview也不例外,但是不同的是webview的首次构造耗时比较长。
可以通过简单的代码来对比一下Webview首次初始化和第二次所花费的时间:private void testWebViewInitUsedTime(){
long p = System.currentTimeMillis();
WebView mWebView = new WebView(this);
long n = System.currentTimeMillis();
Log.i("Info", "testWebViewFirstInit use time:" + (n-p));
}
testWebViewInitUsedTime();
testWebViewInitUsedTime();
//测试环境 Android 7.0 三星S7
testWebViewFirstInit use time:182
testWebViewFirstInit use time:4
可见第二次所用的时间远远小于第一次,这是为什么呢?
通过阅读源码,我们会发现Webview所有的逻辑处理都是通过WebViewProvider来实现的,因为它要加载Webview内核,这是一个重量级的操作,内核是以apk的形式存在。而内核加载后在同一页面是共享的,因此后续的初始化时间就很少了。static WebViewFactoryProvider getProvider() {
...
Class<WebViewFactoryProvider> providerClass = getProviderClass();
sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
.newInstance(new WebViewDelegate());
return sProviderInstance;
}
private static Class<WebViewFactoryProvider> getProviderClass() {
...
loadNativeLibrary();
}
private static int loadNativeLibrary() {
...
String[] args = getWebViewNativeLibraryPaths();
int result = nativeLoadWithRelroFile(args[0] /* path32 */,
args[1] /* path64 */,
CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
CHROMIUM_WEBVIEW_NATIVE_RELRO_64);
}
既然如此,我们可以在App生成一个全局webview,并且在启动时初始化,这样在后面使用时通过动态获取这个全局Webview,然后添加到rootview中,这样就可以进行复用从而减少初始化的时间。
不过需要注意的是,如果在不同页面使用Webview时使用不同的设置,就需要动态维护,而且在不同的页面跳转前要做好清理工作。三.H5页面拉取优化
有了Webview,就要开始拉取H5页面了。针对这一步,我们可以把html,css,js,image等资源预置在客户端本地,并和服务端协商好前端的版本控制和增量更新策略,如此一来Webview就可以先快速加载本地缓存页面资源,剩下的就只需要拉取那些需要更新的增量资源即可。
而针对这些需要拉取的增量资源,可以对它们进行webpack+gzip数据压缩和CDN加速处理,以提升拉取速度。并且在建立网络连接时,可以让前端请求的域名和客户端API接口域名一致,以减少DNS解析时间。
最后,对于H5页面来说,图片资源的拉取是最为耗时的,一个比较好的解决方案就是先加载并展示非图片内容,延迟这些图片的加载,以提升用户体验。
WebView有一个setBlockNetworkImage(boolean)方法,该方法的作用是是否屏蔽图片的加载。可以利用这个方法来实现图片的延迟加载:在onPageStarted时屏蔽图片加载,在onPageFinished时开启图片加载。

四.H5动态数据拉取并行
正常的顺序是在html,css,js拉取下来之后,才开始由js发起前端的ajax请求,获取到数据后才开始进行填充。
其实我们可以把前端的ajax请求提前到和页面加载同时进行,由客户端请求数据,等到H5加载完毕,直接向客户端索要即可,如此一来,便缩短了总体的页面加载时间。

五.总结
除了上述提到的点,其实还有很多其他的方案,比如可以通过静态直出,直接下发首屏html的方式加速首屏的展现,也可以通过智能预取的方式提前进行网络请求数据到本地,甚至有些重度依赖H5的App利用预先准备好数据的Webview池来达到加速的目的。
所以,Webview优化是一个长期的、综合性的工作,有许多细节可以考虑,需要根据业务需求来不断升级优化策略。

8fa13c1adcf676a62dc4f37d0eee3156.gif

一切从android的handler说起(一)之message
一切从android的handler说起(二)之threadLocal
一切从android的handler说起(三)之UI线程不卡顿
一切从android的handler说起(四)之postDelay原理
一切从android的handler说起(五)之触摸事件模型
一切从android的handler说起(六)之生命周期来源
一切从android的handler说起(七)之Handler内存泄露



进入公众号,回复“程序员“可以领取一份计算机技术电子书福利合集

305382f16d8cb3ffd366db61a4085cfe.png


欢迎转发,关注公众号 肖晖
每天几分钟,掌握一个硬核面试知识点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值