技术
介绍
本文探讨如何通过系统的优化措施,大幅提升京东数亿级用户小程序的性能。技术团队从前端渲染优化等方面,实施了一系列创新策略,使小程序性能翻倍。详细介绍了这些优化措施的实施过程和效果,为在大规模用户群上追求极致性能的开发者提供了宝贵的实践经验。
01
前言
今年的敏捷团队建设中,我通过执行器实现了一键自动化单元测试。除了执行器,还有哪些执行器呢?我的探索之旅就从这里开始啦!
小程序性能是指小程序在微信APP或其他宿主APP中加载和呈现的速度,以及小程序对用户交互的响应速度。性能不佳的小程序会出现渲染和响应缓慢,甚至无法正常打开的情况,不同程度地影响了用户体验,导致用户流失。
随着更多业务不断更新迭代,京东购物小程序的启动性能逐渐下滑,微信后台打开率仅有86%,每天流失数百万用户,随着互联网人口红利的结束,增长速度的放缓,如何通过技术手段提升启动性能,才能更好地留住来之不易的增量用户,进一步促进业务增长,成为重中之重。
02
绩效指标与衡量
理解,首先根据模板缓存状态判断网络是否需要获取最新模板,获取到模板后进行加载,加载阶段会将产物转化为视图树结构,转换完成后经过表达式引擎解析表达式,获取正确的值,再经过事件解析引擎解析自定义事件并完成事件绑定,解析赋值、事件绑定完成后进行视图渲染,最终将目标页面展示到屏幕上。
用性能指标来评估小程序的加载速度是非常有必要的,首先我们来回顾一下精购小程序页面加载的关键阶段:
这些关键阶段的含义如下:
阶段
意义
下载小程序代码包
(FP)
页面的第一幅图
(FCP)
第一张有内容的画
(FMP)
第一幅有意义的绘画
(液晶显示)
绘制页面最大内容,实现可交互状态
在上述几个阶段中,最重要的是从用户点击小程序到页面最大内容绘制(LCP)所花费的总时间。
驻龙监控平台已经为京购小程序开发者提供了性能监控指标,通过驻龙监控平台可以测量相应进程的时间消耗,小程序启动流程如图所示:
关键监控指标字段及对应含义如下:
字段
意义
埃
代码包下载需要时间
逻辑层耗时的JS代码注入
首次呈现页面所需的时间
页面切换时间
首次内容绘制 (FCP)
小程序启动时间
最大内容绘制时间 (LCP)
筑龙监控平台根据以上指标的权重以及各指标得分的加权平均值计算出用户体验得分(UEI),如图:
03
如何优化性能?
理解,首先根据模板缓存状态判断网络是否需要获取最新模板,获取到模板后进行加载,加载阶段会将产物转化为视图树结构,转换完成后经过表达式引擎解析表达式,获取正确的值,再经过事件解析引擎解析自定义事件并完成事件绑定,解析赋值、事件绑定完成后进行视图渲染,最终将目标页面展示到屏幕上。
3.1 代码包大小优化(减少小程序初始化耗时)
从上面的精狗小程序启动流程图中我们可以看出,在 App 执行前,主要耗时阶段为代码包下载和代码注入。代码包下载和代码注入的时长与小程序逻辑代码量有关。一般来说,小程序代码包越大,逻辑层代码量就越大,因此初始化耗时越长。这里我们用到了以下技术:
3.1.1 独立分包
“独立子包”可以独立于主包和其他子包运行,从独立子包页面进入小程序时,无需下载主包。
开发者可以根据需要,将某些具有一定功能独立性的页面配置成独立的子包,从普通子包页面启动小程序时,需要先下载主包;独立子包不依赖于主包,直接运行可以大大提高子包页面的启动速度。
对于京购小程序首页,我们通过自主分包的方式开发了京购快车首页并逐步上线购物入口,相比普通套餐,快车首页的启动时间整体缩减,优化了14.5%的启动所需时间,以上收益来自于侧面市场优化效果。
3.1.2 打包异步化
“子包异步化”将小程序的子包从页面粒度细化到组件甚至文件粒度,这样可以让一些原本只能放在主包页面的插件、组件和代码逻辑分离到子包中并在运行时异步加载,进一步减少 大小和启动所需的代码量。
异步分包可以有效解决主包体积膨胀过大的问题。
对于附近生活圈频道页,通过利用分包异步将主包组件移至子包中,附近生活圈占用主包空间由原来的39kb缩减为39kb,大大减少了主包代码大小;公众号、首页、购物车、沃井等模块共同努力,通过异步分包将包大小缩减为31kb;类目Tab大小通过异步分包缩减为6kb。

3.1.3 子包预下载
使用“分包加载”后,虽然可以明显提升小程序的启动速度,但是当用户在使用小程序时跳转到分包内的页面时,需要等到分包下载完成后才能进入页面,导致页面切换缓慢,影响小程序的用户体验。分包预下载正是为了解决首次进入分包页面时的延迟问题。
值得注意的是,独立分包和分包预下载可以配合使用,独立分包时还可以对主包进行预下载。
组件异步引入附近生活圈频道页后,会导致附近生活圈频道各楼层组件的渲染速度降低,因此通过在首页配置预下载分包组件,提前下载附近生活圈分包组件,以解决首次进入附近生活圈页面时组件延迟渲染的问题。
3.2 代码注入优化
3.2.1 按需注入
您可以通过小程序配置选择性地注入必要的组件代码:
{ "lazyCodeLoading": "requiredComponents"}
开启“按需注入”后,小程序仅注入当前访问页面所需的自定义组件和页面代码,未访问的页面及当前页面上未声明的自定义组件将不会被加载和初始化,也不会执行相应的代码文件,以减少小程序的启动时间和运行时内存。
值得注意的是,插件包与扩展库目前还不支持按需注入,如果需要实现按需加载插件,可以考虑将插件放在子包中,通过“子包异步化”的方式异步导入。
3.2.2 减少启动过程中的同步 API 调用
小程序启动过程中会进行代码初始化,并按顺序同步执行App.、App.、Page.、Page.等生命周期函数,此期间应尽量减少同步API调用或不调用。
初始化阶段容易调用的常见同步API有:
1./,可以尝试使用异步版本API代替;
2. / 仅应用于数据的持久存储,不应用于运行时数据传输或全局状态管理。
3.3 首屏渲染优化
页面首屏渲染的优化目的是为了让用户能够更早的看到内容页面绘制(FCP)或者有意义的页面绘制(FMP)。
3.3.1 避免引用未使用的自定义组件
在页面渲染阶段,会初始化并读取当前页面配置和全局配置中引用的自定义组件以及组件依赖的其他自定义组件,引入未使用的自定义组件会影响页面初始化渲染的耗时。
因此,当某个组件不使用时,应及时将其从其中移除。
3.3.2 精简首屏数据
页面首次渲染耗时与页面复杂度成正相关,在精购小程序的很多业务场景中,小程序渲染的页面高度超过一屏,但用户首次进入页面时,超出屏幕的页面内容并不显示,不具备实际意义,因此只需要先渲染可视范围内的内容即可。当页面首屏渲染完成后,再继续异步渲染剩余的页面内容。
因此我们可以在页面首次渲染的内容上做一些取舍,即:
1、如果页面从上到下由多个独立组件组成,可以延迟加载不在首屏范围内的组件;
2、如果页面是由列表项组成的,比如首页的流程,可以主动控制列表项的长度在页面中加载,然后在滑动接近底部的时候加载并渲染更多的列表项。
需要注意的是,与页面渲染无关的数据尽量不要放在data中,避免影响页面渲染的时间消耗。
3.3.3 提前请求首屏数据
由于网络请求需要一定的时间,但小程序页面渲染的数据往往需要依赖服务端接口返回,因此在服务端接口返回数据之前,页面可能还是空白的,或者是骨架屏。
为了尽早发出核心数据请求,可以使用微信小程序提供的能力:数据预取。
“数据预取”可以让微信客户端在小程序启动时,通过微信后台预先从服务端拉取核心业务数据,在加载代码包时,在精狗首页通过wx.ta获取预取的数据,这些数据可以用来更快的渲染首页,减少用户等待时间。具体核心流程如图所示:
3.3.4 缓存请求数据以供初次渲染
除了上述的数据预取能力之外,微信小程序还提供了wx.、wx.等API来读写本地缓存。
在精购首页中,将上一次读取的直出接口的数据保存在缓存中,这样,用户下次初始化首页时,先从缓存中读取首页的直出数据,快速渲染出页面整体视图,等待接口读取完毕后真正返回后再更新页面。
3.3.5 骨架屏
“骨架屏”就是在页面渲染前用一些灰块粗略勾勒出页面轮廓,在页面数据加载完成后再替换成真实内容,骨架屏可以有效避免页面在请求过程中出现白屏,避免用户误以为加载失败而退出小程序;也可以避免异步渲染时不同楼层跳上跳下,影响用户体验。
3.4 其他优化(如发布更新频率)
3.4.1 合理规划版本发布
从小程序更新机制我们可以知道,小程序在启动时如果检测到版本更新,会重新获取小程序基础信息、重新生成初始渲染缓存等操作,这些都会影响页面的启动时长,启动频率可能会导致用户每次重新打开小程序都要更新一次,使得平均启动时长变长。
因此需要提前做好版本规划,控制版本发布和更新的频率。
3.4.2 优先考虑本地版本设置
通过“优先使用本地版本设置”,可以确定部分较新的小程序版本不需要用户更新到最新版本,这个可以在小程序管理后台“设置”-“功能设置”-“优先使用本地版本设置”设置后,用户使用小程序时,客户端会优先开启本地版本代码包,若用户本地版本不低于此版本,则优先使用本地版本,后台会异步更新代码包的最新版本,优先更新到最新版本。
04
总结与展望
理解,首先根据模板缓存状态判断网络是否需要获取最新模板,获取到模板后进行加载,加载阶段会将产物转化为视图树结构,转换完成后经过表达式引擎解析表达式,获取正确的值,通过事件解析引擎解析用户自定义事件,完成事件绑定,完成解析赋值和事件绑定后进行视图渲染,目标
4.1 性能优化总结
在了解了精购小程序的性能指标和启动流程之后,你可以很方便的从驻龙监控平台查看到你所负责的业务对应的页面性能数据,及时发现页面的一些性能问题并及时进行解决优化。
当然,除了上面介绍的前端性能优化策略之外,还可以探索诸如与服务端约定新的数据格式等想法,避免服务端传输无效数据,导致响应内容量过大。
经过以上优化后,微信官方后台数据分析显示,京东购物小程序打开率由优化前的86%提升至90%以上,较优化前每天减少近百万用户流失。
下图是京东购物小程序内测阶段优化前后的真机体验对比。从驻龙监控平台来看,首页整体冷启动时间从100%左右下降到100%以下。打到优化版本后,我们后续会评估业务数据,逐步提升灰度配比,全面提升用户体验。
4.2 未来前景
基于目前在性能优化方面的探索和实践,结合线上实际的统计数据分析,我们会针对“首页渲染”等占用时间比重比较大的环节继续进行深入实践。我们会在这个层面上做更多的尝试,从精简业务数据、尝试新的渲染引擎等,为客户提供更加友好、流畅的用户体验。