0%

Android性能优化-WebView优化

1. 初始化

WebView webView = new WebView(this);

这里需要区分首次和非首次,首次创建WebView需要几百ms,而非首次创建为几ms到几十ms。

可以看到,这里初始化是比较耗时的,而我们有时直接把它放到UI线程,或者写在xml中是有问题,会导致打开页面卡死甚至ANR,应该是放到子线程中初始化结束后才添加到View树中。

这里为了加快显示速度,可以做的优化就是预先创建,又可以延伸到WebView缓存池,但缺点就是会占用一定的内存。

2. 加载

webView.loadUrl("http://www.baidu.com");

这里同样要区分首次和非首次,首次加载可能需要几十ms,而非首次一般为几ms,当然如果在低端机或者比较卡的手机上可能会更慢,所以这个loadUrl最好也是放到子线程中调用。

loadUrl执行结束,并不代表网页加载结束了,网页内部加载是异步的,因此在网页加载结束这段时间内,WebView会一直处于白屏状态,这体验是很差的,应该尽量缩短白屏时间。这个加载过程,主要做的工作有:

  • DNS解析

    将域名解析为IP地址,消耗时间跟网络状况有关,慢的话可能要几百ms或者超过1秒,系统会有DNS缓存。优化方法:IP直连,或者域名预解析。

  • html下载

    下载网页资源,跟资源大小和网络状况有关,可能需要几百ms。优化方法:减小网页资源文件大小,资源压缩。

  • html解析

    解析html文件构建DOM树,跟html的复杂程度有关。另外,有些js用法会导致阻塞解析过程,应该尽量避免。优化方法:避免过多的嵌套,内联css,后置js。

  • 渲染

    绘制到界面上,跟DOM树的复杂程度有关。

另外,腾讯开源的VasSonic,采用了边加载边渲染的模式,避免了加载过程中解析渲染空闲的问题,但这个需要服务端支持,成本比较大。

3. 缓存

WebView支持两种缓存:协议缓存和应用缓存

  • 协议缓存

    这个就是对应http协议头部中的控制缓存字段。通过以下代码设置缓存策略:

    webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
  • 应用缓存

    应用层缓存,需要Web端和App端同时设置才能生效,Web端需要在html文件中指定缓存清单文件:

    <html manifest="xxx.appcache">
        ......
    </html>

    然后清单文件就指定需要缓存的资源文件即可。
    App端也要开启应用缓存:

    webView.getSettings().setAppCacheEnabled(true);    

对应WebView缓存,可以参考这两篇文章:

http://unclechen.github.io/2017/05/13/WebView%E7%BC%93%E5%AD%98%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90%E5%92%8C%E5%BA%94%E7%94%A8/

https://cloud.tencent.com/developer/article/1070671

优化:开启缓存机制,避免每次都去网络加载数据,特别是图片资源。

4. 离线包

通过预先下发离线包,实现快速加载,这里主要的技术问题有:

  • WebView拦截请求

    这个比较简单,设置WebViewClient对象,重写shouldOverrideUrlLoading和shouldInterceptRequest方法即可。

  • 离线包下发

    推拉结合的方式,但都需要寻找时机点,比如WiFi网络下。

  • 离线包压缩

    选择压缩算法,节省用户流量。

  • 增量更新

    只需要下发差异包,而不是下发完整包,采用bsdiff算法进行差异分析和还原。

  • 离线包校验和签名

    校验离线包的完整性,判断是否在下发过程中离线包损坏;校验离线包的签名,判断是否在下发过程中离线包被篡改。

离线包也存在一些缺点,比如需要开发服务端,这个成本就比较大;另外预先加载,可能会浪费用户流量,占用手机空间;离线包的缓存更新可能也是会存在问题。

5. 独立进程

WebView会占用一定的内存,如果使用WebView缓存池占用的内存更多,因此这里可以将WebView放到独立进程中,而且还可以避免内存泄露。不过存在的问题就是多进程问题,进程间调用比较麻烦。

6. 其它优化

  • 静态直出

    其实就是在一次加载过程中,减少请求次数,服务端提前准备好最终数据,客户端一次拉取就结束,不用先拉html,再拉css和js,拉数据等。这个可以用于首屏的html,对于所有的页面都这样处理不太现实。

  • CDN加速

    优化网络连接。

  • 替换图片格式

    比如采用webp格式,能够减少图片大小。

  • 开启硬件加速

    能够提供渲染速度。