WebView 优化
WebView 初始化过程
普通用户的角度
- 交互无反馈
- 达到新的页面,页面白屏
- 页面基本框架出现,但是没有数据;页面处于 loading 状态
- 出现所需的数据
程序上
优化点
- 首次初始化事件:客户端冷启动后,第一次打开 WebView,从开始创建 WebView 到开始建立网络连接之间的时间
- 二次初始化时间:再打开过 WebView 后,退出 WebView,再重新打开 WebView,从开始创建 WebView 到建立网络连接之间的时间
- 初始化完毕后:WebView 加载冗余内容导致的缓慢。如一些复杂的 css 文件,js 文件,png 图片等
1.WebView 初始化时间
一般我们测量一个网页打开的快慢为标准的,都是以网络连接开始作为起点的。但是 WebView 中用户体验到的打开时间需要再增加 70~700ms。这是因为 WebView 需要进行一系列的初始化操作。这也就是为什么在 WebView 中会感觉慢。
- 在浏览器中,我们输入地址时(甚至之前),浏览器就可以开始加载页面。
- 而在客户端中,客户端需要先花费时间初始化 WebView 完成后,才开始加载。而这段时间,由于 WebView 还不存在,所有后续的过程是完全阻塞的。
优化方法:
由于这段过程发生在 native 的代码中,单纯靠前端代码是无法优化的;大部分的方案都是前端和客户端协同完成。
1.1 全局 WebView
方法:
- 在客户端刚启动时,就初始化一个全局的 WebView 待用,并隐藏
- 当用户访问了 WebView 时,直接使用这个 WebView 加载对应网页,并展示
这种方法可以比较有效的减少 WebView 在 App 中首次打开时间。当用户访问页面时,不需要初始化 WebView 的时间。
缺点:
- 额外的内存消耗
- 页面间跳转需要清空上一个页面的痕迹,更容易内存泄漏
1.2 客户端代理数据请求
- 在客户端初始化 WebView 的同时,直接由 native 开始网络请求数据。
- 当页面初始化完成后,向 native 获取其代理请求的数据
这种方法虽然不能减少 WebView 初始化时间,但数据请求和 WebView 初始化可以并行进行,总体的页面加载时间就缩短了。
2.与服务器连接的建立
在页面请求的数据返回之前,主要有以下过程耗费时间:
- DNS
- connection
- 服务器处理
优化方案:
DNS 采用和客户端 API 相同的域名,当我们初次打开 App 时:
- 客户端首次打开都会请求
hflldr.voicecloud.cn
,其 DNS 将会被系统缓存 - 然而当打开 WebView 的时候,由于请求了不同的域名,需要重新获取
xiaofeiddubao.com
的 IP
如果 WebView 的域名与 App 的 API 域名统一,则可以让 WebView 的 DNS 时间全部达到 1.3ms 的量级。静态资源同理,最好和客户端的资源域名保持一致。
3.页面加载和渲染
页面加载有时会是一大部分时间花在图片资源的请求上,因此好的解决方案就是延迟这些图片的加载,先加载并展示非图片的内容。
解决方案:
WebView 有一个 setting 配置方法:setBlockNetworkImage(boolean)
,该方法的作用是是否屏蔽图片的加载。
1 |
|
4. 使用缓存
1 | webSetting.setJavaScriptEnabled(true); |
LOAD_CACHE_ONLY:不使用网络,只读取本地缓存数据
LOAD_DEFAULT:根据 cache-control 决定是否从网络上取数据
LOAD_CACHE_NORMAL:API level 17 中已经废弃,从 API level 11 开始作用同 LOAD_DEFAULT 模式
LOAD_NO_CACHE:不使用缓存,只从网络获取数据
LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者 no-cache,都使用缓存中的数据
5.前端支持
除此之外,前端页面也要控制好资源的压缩,css、js的加载顺序等。