codecamp

支付宝小程序扩展能力 性能解决方案

名词解释

解释
首屏时间 用户开始尝试打开小程序到小程序首屏加载完成的时长
主包 小程序最常用的核心页面(首页、tabBar 页面和其他公共资源)编译压缩后的产出包
IDE 支付宝小程序开发者工具
用户折损率 用户离开小程序占比。(用户全链路访问量 - 用户首页 PV)/ 用户全链路访问量

背景

在大体量的小程序和开发者形态下,小程序质量体验问题逐渐成为大家的关注焦点,如何提高自身小程序质量体验成为所有开发者的课题,而其中性能提升更是发力重点,接下来将和大家介绍支付宝小程序质量团队性能解决方案,同时提供工具使用说明。

首屏时间

首屏时间定义是指用户开始尝试打开小程序到小程序首屏加载完成的时长。

从支付宝性能统计数据中发现,小程序首屏耗时上涨与用户折损率上涨呈正相关,首屏时间过长将影响用户体验,导致用户流失率升高,降低用户对小程序黏性。所以解决小程序性能损耗问题是提升小程序用户使用度、加强用户黏性一项非常重要的手段。

说明:建议首屏时间不超过 3s。

可优化时机

小程序启动过程中需要完成 3 步工作:

step1:运行环境准备

step2:下载、注入、解压对应小程序离线包

step3:渲染小程序首屏

而小程序开发者可以在 step2、step3 中来优化性能。

业务耗时常见问题

小程序质量团队在解决各小程序性能问题中,对业务上耗时常见问题进行归整,如下表所示。

问题描述 影响因素
资源加载量大,流耗大 图像文件(PNG/JPG/GIF)资源过大影响启动耗时
小程序产出包过大影响启动耗时
jsapi 单次请求耗时长 mtop/request/httpRequest/rpc/http 请求因网速慢、加载资源大等导致单次请求耗时
setData 一次传输数据量过大,导致首屏构造节点太多影响启动耗时
jsapi 接口进行同步调用 获取系统信息 jsapi(getSystemInfo)接口启动小程序时即进行同步加载,待执行完成后进行后续业务逻辑
设置数据缓存 jsapi(setTinyLocalStorage)接口同步调用
业务相关 jsapi(如 getCurrentLocation、getCities)同步调用
jsapi 耗时接口多次/重复调用 request/httpRequest/mtop/rpc 等请求网络相关 api 接口多次调用
获取系统信息(getSystemInfo)/获取用户授权(getAuthCode)/获取用户信息(my.getOpenUserInfo)/获取客户端信息(getClientInfo)等 jsapi 接口重复调用
setData 请求调用次数过多
jsapi 接口串行调用 设置小程序本地缓存(setTinyLocalStorage)/获取小程序本地缓存(getTinyLocalStorage)等 jsapi 接口交替串联调用,即 setTinyLocalStorage > getTinyLocalStorage > getTinyLocalStorage 连续执行调用
request/httpRequest 等 jsapi 网络请求接口连续执行,发送请求
生命周期函数执行时机不合理 onReady 生命函数中执行相关请求将导致首屏渲染延缓
废弃 jsapi 继续使用 httpRequest 已被 request jsapi 接口所替代

优化建议

img

控制小程序资源包大小

当用户访问一个小程序时,支付宝客户端会首先从 CDN 下载小程序资源包,所以资源包大小会影响小程序启动性能。

随着小程序离线包大小的上升,耗时也会相应增加,主包大小将决定下载耗时高低。

优化建议

  1. 及时删除无用的图片资源,因为图片资源会默认打包;

  1. 及时清理无用代码;

  1. 使用 分包 进行包大小优化;

说明:建议主包大小不超过 1M

控制小程序图片大小

图片资源是小程序加载资源项中应用范围最广、影响最大的一部分,除去对启动过程中包资源大小的影响,还体现在 API 网络请求中对图片资源的加载。

在治理过程中我们发现,图片的优化不能仅仅存在于小程序的上线环节,后续活动的投放、运营图片的变更场景上也存在,所以图片资源治理建议长期保持,持续对待。

优化建议

  1. 避免使用大图,压缩图片大小。

说明:建议图片资源大小不超过 60KB。

  1. 根据显示区域大小合理控制图片大小。

说明:建议图片宽高不超过实际显示宽高的 3 倍。

  1. 格式转化,可将图片格式转化成 SVG/webp。

  1. 大图建议从 CDN 渠道上传,且并发加载数量需要控制,可考虑使用雪碧图技术或在屏幕外的图片使用懒加载。

说明:建议每秒发起的图片请求不超过 20 个。

  1. 图片开启 HTTP 缓存控制,下次加载同样图片,直接从缓存读取。

首屏数据缓存

官方文档提供 my.setStorage / my.getStorage 等异步读写本地缓存的能力,数据存储在本地,返回的会比网络请求快。对于部分网络请求数据,可优先从缓存中获取数据来渲染视图,等待网络请求返回后进行更新。

优化建议

网络请求影响视图渲染的数据,可设置数据缓存,存储本地。

将数据请求提前至 onLoad

小程序运行中,会先触发页面的 onLoad 生命周期函数,再将页面初始数据(Page data)从 worker 传递到 web-view 进行一次初始渲染。

页面初始渲染完成,从 web-view 发出通知到 worker,触发 onReady 生命周期函数。

部分小程序会在 onReady 中发出请求,导致首屏渲染延缓。

优化建议

将数据请求提前到 onLoad 中。

控制接口同步调用

小程序接口使用太多的同步调用方式,也会造成加载耗时被拉长。同步 API 的使用过多将造成进程的阻塞,影响后续业务逻辑的执行。

getSystemInfo 获取系统信息、getStorage 缓存等是业务方最常见会引起同步调用的 API,同时还有业务相关逻辑的 getLocation、getCities 等 API 也是同步调用的 高发区。

优化建议

API 同步执行转化成异步执行。

控制接口单次耗时

接口耗时太长会让用户一直等待甚至离开,接口的耗时有小程序 API 调用耗时、页面渲染耗时,同时也有服务器处理时间。

分析数据中发现,mtop/request/rpc 等网络请求慢、setData 传输数据过多是耗时长的主要原因,同时有部分 API 容易造成耗时长,例如 getLocation、getSystemInfo 等。

优化建议

  1. 处理好服务器处理时间,可减少回包大小,可服务端 rpc/mtop/http 等网络请求预加载,让请求快速响应。

说明:建议网络请求接口单次耗时不超过 600ms。

  1. 缩短单个 API 接口的耗时时长。

说明:建议小程序接口单次耗时不超过 200ms。

控制接口调用次数

数据分析中发现小程序启动过程中有相当多接口有多次、重复以及串行调用的情况。

  • 多次调用:指 API 接口前方执行完毕后,单页面后续继续执行同名 API 情况,如获取系统信息(getSystemInfo)/获取用户授权(getAuthCode)/获取用户信息(getUserInfo)/获取客户端信息(getClientInfo)等 API 接口多次调用;
  • 重复调用:指 API 接口多次调用中,存在着重复请求的情况,最常见的是多次网络请求 request 而其中 url 相同;
  • 串行调用:指 API 交替使用,该使用方式极不规范且追加无用耗时,如设置缓存(setStorage)/获取缓存(getStorage)等 API 接口串行交替调用。

优化建议

  1. 减少单页面同名接口调用次数。

说明:建议单页面业务相关 API 接口调用次数不超过 3 次,网络请求接口不超过 10 次。

  1. 采用缓存方式处理,将前一执行接口后的结果数据以缓存形式保存。

  1. 杜绝 API 串行交替调用的方式,减少冗余耗时。

控制 setData 渲染节点数量和大小

业务请求返回后,会调用 setData 触发页面重新渲染,可参考如下执行过程:

  1. 数据从 worker 传递到 web-view。
  2. web-view 上根据传过来的数据构造虚拟 DOM,并与之前做差异比较(从根节点开始),然后渲染。

由于 worker 与 web-view 通信时,数据需要序列化,然后到了 web-view 需要执行 evaluateJavascript,因此如果一次性传输数据太大,会影响首屏渲染性能。

另外,如果 web-view 上构造节点过多,层级嵌套太深,例如有的小程序列表页面一次性渲染超过 100 个列表项,每个列表项又有嵌套内容,而实际上整个屏幕可能只是显示不到 10 个, 会导致差异比较时间较长,同时由于是首屏渲染,会一次性构造很多 DOM,影响首屏渲染性能。

优化建议

  1. setData 数据量不宜过大,避免一次性传递过长的列表。

说明:建议 setData 的数据在 JSON.stringify 后不超过 256KB。

  1. 首屏请勿一次性构造太多节点,服务端可能一次请求传递大量数据,请勿一次性 setData,可先 setData 一部分数据,然后等待一段时间(比如 400ms,具体需要业务调节)再调用 $spliceData 将其他数据传输过去。

  1. setData 接口调用频率减少,避免无用的频繁调用。

说明:建议 setData 单页面调用次数不超过 20 次。

附录A:优化 setData 逻辑方案明细

工具说明

针对上述可优化点的检测,小程序质量团队推荐如下性能分析工具:商家自审核/性能调试,协助广大开发者对小程序进行性能缺陷的识别和分析。

附录B:商家自审核工具使用

附录C:性能调试工具使用

支付宝小程序扩展能力 质量体检
支付宝小程序扩展能力 附录 1:优化 setData 逻辑方案明细
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

支付宝小程序开发文档

支付宝小程序 快速示例

支付宝小程序 小程序快速示例

支付宝小程序 框架

支付宝小程序 组件

支付宝小程序组件 基础组件

支付宝小程序组件 无障碍访问

支付宝小程序 扩展组件

支付宝小程序扩展组件 UI组件

支付宝小程序 API

支付宝小程序 开发工具

支付宝小程序 云服务

支付宝小程序 Serverless

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }