背景
C端支付宝小程序《青团社兼职》随着业务不断增加,加上主包、分包疏于管理,造成了主包越来越大,导致启动耗时被支付宝洞察网站标记为不合格。
第一次优化:主包瘦身
看了一下主包pages文件夹大概有4M大小,内容非常多,200+page页面,以下是优化步骤:
1.小程序管理后台查看访问量低于40的页面,咨询产品、C端开发组员,确认哪些页面是可以删除的。
2.确认哪些模块可以拆分到分包
●2.1 查看影响到的页面功能点,找到对应的产品负责人进行沟通了解。
●2.2拆到分包以后,相对路径修正,关注引用组件是否会受影响(比如分包引用分包组件,不合理,需要调整)
3.多余文件删除
目前主包为1.8M,缩小了一半多。
第一次优化结果
启动耗时指标只下降了几十毫秒,还是不及格;
资源流耗指标从2700kb下降到了1923kb,达到中等评价。
缩小主包体积这个方案的效果不理想,和我们想法出入很大,所以找了支付宝官方同学咨询。
第二次优化:首页性能优化
结合支付宝开发工具-->性能调试,作出以下优化:
1.发现首页多搜索框是直接用的图片,改为用代码实现,减少图片请求次数。
2.小图标使用压缩版本链接(ps:图标必须为正方形 `${link}-100`)
3.将首页的小图标用iconfont替换,减少图片请求次数。
4.getStorageSync、getSystemInfo等同步api频繁调用导致主流程时间过长
●4.1优化同步api不合理使用
●4.2发现fundebug sdk中会调用getNetWorkType,大概会阻塞400ms-800ms左右,删除fundebug(目前支付宝小程序云监控已经没有严重的bug,可以去除)
5.setData回调中再次执行setData,发现页面某些方法中存在setData回调中嵌套回调的问题,将不合理回调去除。
6.首次加载setData调用多次,不需要渲染的数据也用了setData,去除不合理setData,将多次setData使用$spliceData合并成一次。
7.首页接口请求过慢的找服务端童鞋协商。
8.接口没有依赖关系的可以考虑使用Promise.all()
第二次优化结果
优化前:
优化后:
可以发现同步阻塞的非常严重,耗时大概1600ms左右,优化后阻塞问题确实得到了比较大的改善,耗时已经降低到400ms,但是实际大盘数据并没有得到这么大的改善.
启动耗时由3部分组成:容器耗时+Engine耗时+纯业务耗时
前后版本对比,纯业务耗时降低了300ms,Engine耗时降低了200ms,容器反而增加了300ms,支付宝官方解释新版本拉包会上涨,导致容器耗时增加,后续会逐渐稳定,
所以本次优化实际降低了大概500ms。
第三次优化:TOP5启动耗时过长页面优化
找到小程序页面访问量前5的页面,针对这5个页面做优化。
1.图片资源压缩
2.getStorageSync、getSystemInfo等同步代码优化
3.setData调用合并
4.逻辑优化,接口并发
第三次优化结果
通过各页面数据对比,发现除了小程序首页的《新人专区》的启动耗时还是有6100ms,其他页面都有明显的改善,数据大盘的启动耗时也终于达标,低于4000ms,如下图所示。
第四次优化:架构调整
登录态、地理位置状态等全局管理,使用redux状态管理工具,作为用户数据做统一的读取、设置,将之前全局动则使用getStorageSync、setStorageSync来操作数据导致的大量同步阻塞问题从根本解决。
第四次优化结果
去除了大量的同步缓存读取以后,数据基本稳定在3600ms左右。
优化过程中遇到的困难
1.优化时没有量化指标,ide提供的性能测试或者云测提供的帮助微乎其微,初期甚至按照自己的一套规则去计算各阶段的时间差来衡量某块代码是否达到了优化目的。
2.优化以后需要T+2甚至T+3之后,然后找支付宝童鞋提供对应页面的timeline来确定优化效果以及后续优化方向。
3.前端开发迭代多个版本后存在大量的冗余代码,模块化管理意识不够。
4.系统信息、用户信息、登录态等没有统一管理,往往做一个改造都要全局去动代码,风险大、代码管理难以把控。
4.代码规范不到位,少注释、setData多次调用、setData回调嵌套等等,往往优化的过程中就需要找相关同学梳理逻辑,之前大家在性能方面的考虑还是太少。
与传统h5性能优化有哪些异同点
相同点:
1.图片优化手段,懒加载、雪碧图、iconfont
2.接口并发,同步代码改造
3...
不同点:
1.小程序需要专门对setData操作优化,包括setData次数、内容大小,h5没有这方面的限制
2.现在h5的主流都集成了工程化,可以实现tree-shaking (是无用代码移除)、Code Splitting(按需加载)、scope hoisting(作用域提升)等等功能,
而我们的小程序在这方面还是有所欠缺。
3.h5优化的时候有一些比较清晰的优化指标,比如:
●首次有效渲染(FMP,是指主要内容出现在页面上所需的时间),
●重要渲染时间(页面最重要部分渲染完成所需的时间),
●可交互时间(TTI,是指页面布局已经稳定,关键的页面字体已经可见,主进程可以足够的处理用户的输入 —— 基本的时间标记是,用户可以在 UI 上进行点击和交互),
●输入响应,接口响应用户操作所需的时间,
●Speed Index,测量填充页面内容的速度,分数越低越好。
而小程序是在三方环境中,除了三方给出的一些指标定义,我们还缺少结合本身业务对指标的理解和定义。
4.h5的服务端渲染和gz压缩都可以有效的提高页面渲染速度,但是小程序并没有给开发者提供这种功能,其实小程序对开发者来说更像是一个黑盒,对黑盒的了解程度在一定程度上决定了我们小程序的质量。
5...
你可能不知道的支付宝小程序特性
1.支付宝的启动耗时指标,是所有入口页面的一个平均的指标,而不是我们所认为的小程序首页启动耗时。
2.分包页面作为入口页面,会增加启动耗时,加载分包会有额外的js调用,所以分包页面如果会作为入口页面并且量级大的话,建议放入主包。
3.启动耗时=容器耗时+Engine耗时+纯业务耗时,我们所做的优化,都是在纯业务耗时上做努力。
4.小程序加载的时候,会加载主包中所有页面的js文件,以及json中引用组件的js文件,所以js文件顶部以及data预设部分不要做同步操作,比如getStorageSync等操作,会阻塞整体代码的执行。
5.每次发版版本的时候,用户都要重新拉取新包,会增加容器耗时和Engine耗时,所以把控发版频率有助于启动耗时的稳定。
6.经过实践,控制主包大小效果并不是特别突出,应该直接优化启动耗时过长的页面。
7.曝光埋点的api?IntersectionObserver会增加启动耗时。
写在最后
●性能问题不会只出现在支付宝小程序上,后续监控系统的搭建就显得非常有必要,我们该如何结合自身业务定义小程序性能指标,sdk怎么写才能不影响业务方的性能,接入的时候是所有业务接入到一个监控应用里,还是像fundebug一样每个项目对应一个监控应用,当出现性能问题的时候该如何告警等等,这些都是不得不面对的问题。
●有了一套自己的东西,在后续的持续优化上才能给我们一个量化的标准,寻找三方帮助肯定没有我们自己效率高。
(ps:写的不对的地方欢迎指出,有好的想法也可以补充进来)