事情,要从一个周末惬意的下午开始说起……
那天,手机突然被唤醒,弹出多条微信消息。原来是这周末正在校园推广的活动群发来的,想起之前大家有条不紊的开发进度,和产品沟通的友好过程,应该是活动反响不错。
现实是残酷的:
“我们的小程序打开慢成狗!”
“这个 loading 加载的过程也太久了!”
“滚动加载有点卡,而且很容易报错……”
看到的是最直接的控诉。
看到用户的录屏,这几个问题确实是有出现,所以我们还是需要对小程序进行一次主流程的性能优化,三句控诉可以总结为3个点:
- 小程序启动慢
- 小程序请求慢
- 小程序交互慢
收到反馈后第一反应是,用户是不是网速太慢了,自己跑一遍,发现自己的手机跑起来都是没问题的,灰常流畅,下意识的可能想录个屏回复过去。
不过有用户录屏在那,当然不能这么草率,所以我们查了下管理后台小程序在不同网络下的大盘数据:
网络 | 启动耗时 |
总体 | 3.6s |
WIFI | 3.5s |
4G | 3.9s |
2G/3G | 4.1s |
从统计看,总体 3.7s的启动耗时 ,网络对于启动耗时是会有影响的,但影响没有很大,就算是2G-3G下跟大盘的数据对比也没有慢很多,可见事情并不简单。
于是我们从另外一个维度来看一下大盘数据:
机型 | 启动耗时 | JS注入 | 初次渲染 |
总体 | 3.6s | 0.29s | 0.16s |
高端机 | 2.9s | 0.19s | 0.06s |
中端机 | 4.8s | 0.42s | 0.19s |
低端机 | 7.9s | 0.72s | 0.43s |
从这里就可以看出问题来了,手机的性能对于小程序的启动速度影响非常大,低端机相对高端机有2-3倍的差距,特别是渲染层甚至有5-6倍的差距,而且问题反馈的用户所使用的手机也确实是中低端机,但用户使用什么手机我们也没法控制,那这里有办法去优化吗?
针对这个问题,我们需要了解一下小程序的启动过程,根据官方文档的介绍,小程序的启动可以分为下面几个步骤:
上图描述了用户点击小程序开始到页面开始请求数据的一个完整的冷启动过程,而小程序初始化的过程(信息准备、环境准备)占用了比较长的时间,但这部分的工作是由微信客户端来完成,开发者无法干预,所以我们只能聚焦于后续的步骤(下载代码包、注入代码包、初次渲染)。
根据官方文档的介绍,这一部分的可优化手段有:
- 减小代码包体积
- 降低代码复杂度
- 减少同步代码接口调用
- 降低页面结构复杂度
- 减少自定义组件数量
后面4条在技术上没有特别好的限制手段,需要我们在 Code Review 的时候对复杂度和开销大的接口调用进行把关,复杂度这里还可以借助如 CodeCC(腾讯内部代码检查工具) 这类工具去进行分析,减少自定义组件数量,这个是比较难以抉择的,需要在代码可读性、可复用性之间做个取舍,不是本次优化的重点。
所以我们就重点关注的代码包体积问题,通过我们的 CI 记录可以收集到我们的总包大小:
可以看到主包体积达到1949.71KB,接近了2M的极限了,在通过依赖分析后,发现除了一些是未使用到的模块和组件外,很大一部分内容是静态资源,同时我们也在官方文档中看到这样一句话:
小程序代码包在下载时会使用 ZSTD 算法进行压缩,这些资源文件会占用大量代码包体积,并且通常难以进一步被压缩,对于下载耗时的影响比代码文件大得多。
所以我们要减小代码包的体积,最直接的方法就是将非必要的资源去除掉:
- 对静态资源进行优化,将非必要的静态资源文件上传到CDN
- 对小程序的组件进行依赖分析,过滤掉未使用的组件
同时我们还关注到,有一些分包特别小,但是由于是普通分包,在打开这些页面的时候还需要先下载主包,这里在包下载耗时上其实是有一些浪费的,比较典型的就是 WebView 页面,他们往往只需要对参数进行处理,对于主包的依赖不是很强,所以这里还有一个可以优化的点:
- 对独立性比较强的页面进行独立分包,尽可能的减少包下载耗时
我们通过日志查到这个用户的首页数据请求返回会到3-4s,请求慢在正常情况下会有这么两种情况:
- 并发量突增导致服务器响应慢
- 用户网速较慢导致发送请求和接收请求变慢
我们通过日志统计发现用户的访问时间端,请求量跟平时保持一致,看大盘请求耗时的统计,也没有产生大的波动: