WebView 的优化
WebView 启动过程大概分为一下几个阶段:
注意:在APP 中打开WebView 的第一步并不是建立连接,而是启动浏览器内核。
以下通过加载流程各节点耗时分析优化
1 WebView 创建初始化
首次初始化WebView 的时间会比较长。初始化后,即使WebView 已释放,但一些WebView 共用的全局服务/资源对象仍未释放,之后初始化不需要生成,因此初始化变快。
可以在客户端启动的时候,就初始化一个全局的WebView ,这种方法可以比较有效的减少WebView 在APP 中的首次打开时间。但是,这也带来了一些问题, 额外的内存消耗;页面间跳转需要清空上一个页面的痕迹,更容易内存泄露。
代码如下所示:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
WebView mWebView = new WebView(new MutableContextWrapper(this));
}
}
2 客户端代理数据请求
在客户端初始化WebView 的同时,直接由native 代码开始网络请求数据;当页面初始化完成后,向native 获取其代理请求的数据。 此方法虽然不能减小WebView 初始化时间,但数据请求和WebView 初始化可以并行进行,总体的页面加载时间就缩短了。
3 资源本地化
客户端预置资源,并维护网络图片url 和本地图片自检的关联,根据一定策略保证本地预置资源为最新资源。若预置资源不限于图片资源,由于html 、js 、css 等资源容易发生变化,因此还需实现一套机制实现本地资源和服务端数据及时的更新。即服务端需要支持版本控制和资源增量下发等功能。
服务端下发填充好首屏数据的网页,作为网页首屏展示,减少网页上数据请求时间。APP 闲置状态时,下载离线包到本地,加载时优先加载离线包数据。后续更新接收下发的差异包,与当前离线包合并成完整包。
方式一:JS 方法注入
private class JsInterface {
@JavascriptInterface
public String getLocalSrc(String src) {
return "file://storage/emulated/0/app/file/a.jpeg"
}
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String js = "javascript:(function() { " +
"var objs = document.getElementsByTagName('img'); " +
"for (var i = 0; i < objs.length; i++) { " +
"var imgUrl = objs[i].getAttribute('src'); " +
"var localUrl = window.local_obj.getLocalSrc(imgUrl); " +
"if (localUrl) { " +
"objs[i].setAttribute('src', localUrl); " +
"} } })()";
view.loadUrl(js);
}}
方式二:请求拦截
webView.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.contains("logo.gif")) {
InputStream is = null
try {
is = getApplicationContext().getAssets().open("image/abc.png")
} catch (IOException e) {
e.printStackTrace()
}
WebResourceResponse reponse = new WebResourceResponse("image/png", "utf-8", is)
return response
}
return super.shouldInterceptRequest(view, url)
}})
4 DNS 解析耗时
以美团为例,美团的客户端请求域名主要位于api.meituan.com ,然而内嵌的WebView 主要位i.meituan.com 。初次打开APP 时:客户端首次打开都会请求api.meituan.com ,其DNS 将会被系统缓存。然而当打开WebView 的时候,由于请求了不同的域名,需要重新获取i.meituan.com 的IP ,这样用户打开WebView 时就在DNS 上耗费了时间。
DNS 会在系统级别进行缓存,对于WebView 的地址,如果使用的域名与APP 的API 相同,则可直接使用缓存。
5 绘制渲染
布局绘制是一个递归过程,从呈现根节点开始,递归遍历子节点,计算几何集合信息。因此,html标签越复杂、嵌套越深,则布局耗时越久。
优化网页布局,减少布局层次。
参考
https://www.jianshu.com/p/0042813168f7
https://www.jianshu.com/p/56e2b0bf9ab2
https://www.jianshu.com/p/7a237e7f055c
https://blog.csdn.net/weixin_40438421/article/details/85700109
https://zhuanlan.zhihu.com/p/161964699
https://www.jianshu.com/p/7f99a0f040a6
https://www.jianshu.com/p/6179d51281da
|