在进行启动优化之前,我们先介绍一下小程序的启动过程。了解小程序的启动流程,可以帮助开发者更有针对性地选择性能优化的手段,分析性能优化的效果。
本文的启动流程以安卓和 iOS 为准,其他平台可能会略有差异。
小程序启动过程主要包括以下几个环节:
小程序启动的各流程不是串行的,会尽可能的并行。计算耗时不能简单加和。
小程序启动的各流程不是每次启动都完整进行的,会尽可能的利用缓存。
# 1.1 小程序相关信息准备
在用户访问小程序时,微信客户端需要从微信后台获取小程序的头像、昵称、版本、配置、权限等相关信息,以对小程序进行必要的版本管理、权限控制和校验等。
为了在保证信息实时性的前提下,尽量降低对启动耗时的影响,这些信息会在本地缓存,并通过一定的机制定期进行更新。
信息的获取和更新需要发起网络请求。请求分为两种情况:
(1) 同步请求:会阻塞小程序的启动流程,影响小程序的启动耗时。有以下情况需要进行同步请求:
- 首次请求:用户首次访问该小程序(或小程序被清理)时,客户端没有缓存,需要同步请求小程序相关信息。
- 同步更新:微信会在后台定期检查经常使用的小程序是否更新。如果启动时已知小程序有新版本,会同步更新信息。
- 强制更新:用户长时间未使用小程序时,为保障信息的实时性,会强制同步更新信息。
(2) 异步请求:与启动流程并行,不影响启动耗时。主要发生在:
- 异步更新:已使用过的小程序,定期检查暂未发现小程序有新版本,则优先使用本地缓存的信息完成启动,并异步进行更新。
# 对启动耗时的影响
在用户首次访问小程序、小程序版本更新或使用长期未使用的小程序时,信息的获取和更新会影响小程序的启动耗时,耗时长短与网络环境有关。
# 1.2 运行环境准备
小程序的运行环境包括小程序进程、客户端原生部分的系统组件和 UI 元素(如 导航栏、tabBar 等)、渲染页面使用的 WebView 容器、开发者 JavaScript 代码的运行环境、小程序基础库等等。
部分环境(如 JavaScript 引擎、小程序基础库)需要在执行小程序代码之前准备完成,其他的会与代码注入并行进行。运行环境的准备时间相对较长(尤其是在低端设备上),会对小程序启动产生严重影响。
为了尽可能的降低运行环境准备对启动耗时的影响,微信客户端会根据用户的使用场景和设备资源的使用情况,依照一定策略在小程序启动前对运行环境进行部分地预加载,以降低启动耗时。我们希望小程序启动时尽可能都使用预加载的环境,但由于受到设备资源和操作系统调度的影响,预加载会有一定的失败率,并不能保证每次小程序启动时都可以命中预加载的环境。
# 对启动耗时的影响
运行环境准备耗时较长,如果启动时没有命中预加载的环境,对小程序的启动耗时会有明显影响。耗时长短与平台、设备性能、预加载比例有关。
- 由于系统功能和启动流程实现的差异,通常安卓系统运行环境准备耗时要远高于 iOS。
- 低端机系统资源比较紧张,预加载的环境会更容易被系统清理,导致预加载比例偏低。
- 预加载比例越高,平均启动耗时一般可以越低。
# 1.3 代码包准备
小程序启动时,需要根据用户访问的页面,从服务器获取代码包地址,下载小程序代码包,并对代码包进行校验。根据小程序页面所在分包和使用的插件不同,一次启动可能需要下载多个代码包或插件包。
除了启动过程,代码包下载在页面跳转、预下载、使用分包异步化等过程中也会触发。
为了在保证用户尽可能访问新版本的前提下,尽量降低对启动耗时的影响,小程序代码包会在本地缓存,并通过更新机制定期进行更新。
和相关信息准备类似,代码包下载也会有同步和异步两种情况:
(1) 同步下载:会阻塞小程序的启动流程,影响小程序的启动耗时。有以下情况需要进行同步下载:
- 首次下载:用户首次访问该小程序(或小程序被清理)时,客户端没有缓存,需要同步下载代码包。
- 同步更新:对于小程序信息发生「同步更新」或「强制更新」的情况,如果检测到小程序版本更新,会同步下载代码包。
(2) 异步下载:与启动流程并行,不影响启动耗时。主要发生在:
- 异步更新:对于小程序信息发生「异步更新」的情况,如果检测到小程序版本更新,会异步更新代码包。
为了降低代码包下载的耗时,我们采用了包括但不限于以下方式:
- 代码包压缩:采用 Zstandard 算法对小程序代码包进行压缩,以尽可能降低下载过程中传输的数据量。
- 增量更新:当代码包发生更新,不需要重新下载完整的代码包,只需要下载根据算法生成的体积很小的增量包进行更新。
- 更高效的网络协议:下载代码包优先使用 QUIC 和 HTTP/2。
- 预先建立连接:在下载发生前,提前和 CDN 建立连接,降低下载过程中 DNS 请求和连接建立的耗时。
# 对启动耗时的影响
下载耗时是启动耗时中的重要瓶颈,在用户首次访问小程序或小程序版本更新时,代码包的下载会对启动耗时造成影响。耗时长短与网络环境,代码包压缩后大小,以及是否命中增量更新有关。
考虑到包大小对用户体验的影响,平台限制单个小程序代码包的大小上限为 2M。代码包上限的增加,对于开发者来说能够实现更丰富的功能,但对于用户来说也增加了流量和本地空间的占用。为了保证启动速度,开发者应该尽可能的控制启动时用到的代码包大小。