QQ音乐客户端Web页面通用性能优化实践
程序员成长指北
共 4379字,需浏览 9分钟
· 2020-09-11
一、问题与目标
1. 前端优化的局限
无法规避 WebView 初始化耗时 受限于 WebView 生命周期范围
![](https://filescdn.proginn.com/6b0237566983583ab086385cbf2680a7/a9b81252c4e86c53d33fc283c4043f78.webp)
2. 跨端优化的局限
3. 目标
![](https://filescdn.proginn.com/7deecfe9a15c25ae3be306693fe8107c/e56e12db8d37e62172a956be545f71a8.webp)
二、指标设计
1. 客户端现有性能指标数据
![](https://filescdn.proginn.com/04a5ef078e396841589cef15a3e2201f/8e7dc53e50e5e8bd6f962e078cabc787.webp)
(1)客户端 WebView 回调
![](https://filescdn.proginn.com/1a1633cfcf7fa7c6a3eae892b142f5b4/87b7fa8b179dede4425cb2c6f93733d7.webp)
其中,
onMainFrameFinished
取第一个非主请求 (HTML) 的资源被拦截的时机。对于绝大多数页面来说,此时已经完成主请求 (HTML) 的下载,并已经开始解析;可以粗略代表主请求流程结束。
(2)W3C Performance Timing
![](https://filescdn.proginn.com/06c79366d70c772ae1b455a7cbd255af/b2081474e6907fd2f1fe982396691345.webp)
2. 各端单独采集的局限
(1)前端采集的局限
无法独立获取 WebView 开始初始化的时间点。 想获取最精确的加载完成时间点,主要依赖手动埋点。
(2)客户端采集的局限
CSR 页面需在前端页面框架加载后再展示数据,内容请求完成并上屏,发生在页面加载完成之后 SSR 页面的首次内容上屏可携带首屏数据,因此在页面加载完成之前,页面内容已经可以被消费
![](https://filescdn.proginn.com/1cbcb6b269ef1eee5a47edc4f0fe7069/068a1e2fa92015babf880e5e7f6b2863.webp)
![](https://filescdn.proginn.com/b75b1db12151c74492f4ce86238276b0/d45d9331a4f332874790f49942909ad9.webp)
3. 指标设计方案
最准确的页面加载完成时机来自前端 最准确的 WebView 初始化时机来自客户端
(1)前端侧
前端通过手动埋点或监听 DOM 节点数变更,获取加载完成时间点。 前端统计时调用客户端提供 JSAPI,获取以 WebView 初始化时间点作为起点的耗时。 并由前端完成加载耗时的计算和统计上报。
![](https://filescdn.proginn.com/97fb5caa21689b04d6e52d959bf2ba4a/c6cd843b3ce8323247c097a579d97fcd.webp)
(2)客户端侧
前端 domInteractive
时,已完成所有页面展示必需资源的请求和处理耗时的差异,可以体现任何页面的客户端通用优化效果 可以衡量SSR(服务端渲染) 页面的可消费耗时,和CSR(客户端渲染)页面的首帧耗时
webView.evaluateJavascript(
script = “(function(){return performance.timing.domInteractive;})();”,
callback = { value ->
responseEndDuration = value.toLong() - getOnCreateTimestamp()
}
)
虽然 WebKit 负责维护 Performance Timing 的值,但是 WebView 并未提供接口获取上述时间点的值。
三、优化方案和效果
1. 优化方案概述
TBS (X5 内核) 环境预加载 WebView 实例池 主请求并行加载 Web 公共资源池 跟肤逻辑优化
![](https://filescdn.proginn.com/9c660e9f4a1b9fe27a2c918576c29987/4c3540c4b1223c77fd82deaf64a94ded.webp)
![](https://filescdn.proginn.com/1ae5e0cff697a89c06d57c42e513fa92/64234f5b2348bb6326ecacfddfab85e3.webp)
2. 优化手段说明
(1)WebView 初始化
(2)客户端自建缓存
![](https://filescdn.proginn.com/348016e119200b1b17f5e07b730552fe/c036d02f546a763a50791db96dee0c12.webp)
(3)公共资源内联
单线程模型导致读写性能下降 被拦截资源的数量越多,对性能的影响越容易被放大
公共资源加载到热缓存后,转换为对应的 HTML 节点 主请求并行加载完成后,直接在主请求字节流中替换其对应的外联节点;替换后的新字节流返回 WebView
![](https://filescdn.proginn.com/f2f216c523ca5d9c9e2bfa230343ac2c/e46f5aed7acc9476644445d2ce3cbcf0.webp)
3. 优化效果
加载耗时降低 26.2% (1932ms → 1426ms) 跳出率降低 停留时长中位数增加
![](https://filescdn.proginn.com/370f01c2f430cd322690edc6c36d0adc/ae9c5c2cdaf9b1bd81274f998e03f3d9.webp)
四、跨端场景的瓶颈与对策
1. 前终端通信通道效能不足,考虑 “少次多量”
WebView 通道不支持较大量级数据的传递 通信线程多为单线程,甚至需要在主线程发起或处理通信 对传递次数的敏感程度大于对传递数据总量的敏感程度
2. 扩展生命周期
3. 精简 / 前置公共库代码
五、总结与展望
[1] 微信小程序的双线程模型:
❤️爱心三连击
1.看到这里了就点个在看支持下吧,你的「在看」是我创作的动力。
2.关注公众号
程序员成长指北
,回复「1」加入Node进阶交流群!「在这里有好多 Node 开发者,会讨论 Node 知识,互相学习」!3.也可添加微信【ikoala520】,一起成长。
“在看转发”是最大的支持
评论