更新时间:2023-07-28 17:43:21贡献者 3收藏订阅更新我的文档设置返回文档说明小程序启动是线上用户体验的重要影响因素之一。小程序启动耗时与用户的流失率呈正相关,启动耗时越长,越影响用户的使用体验,最终导致用户的流失率升高。因此,支付宝将小程序的首屏启动耗时作为小程序性能的优劣衡量指标。首屏启动耗时定义首屏启动耗时是指用户从点击访问小程序到小程序首屏内容全部显示出来的时间,代表了用户可以感受到的页面加载完成、可进行交互的时间。耗时过长会导致用户看到的都是白屏或者内容有缺失,用户需一直等待内容加载完成,导致用户流失率升高。注意: 首屏非凯发k8官方网娱乐官方首页,所有启动小程序的首个页面都是首屏启动页面,都会影响线上启动耗时。小程序启动可以简单的分为小程序资源准备阶段和业务加载渲染阶段。开发者可以优化的部分主要在代码包准备、网络图片、jsapi 接口调用、setdata、网络请求几个方面。下面根据以往小程序性能治理的经验,分享相关的凯发app官方网站的解决方案供小程序开发者参考。代码包准备优化小程序包体积说明当小程序启动时,支付宝客户端会从 cdn 进行小程序离线包下载,包大小直接影响了下载耗时,而下载耗时是启动耗时重要的影响因素。标准●未分包情况下,包总和上限是 2m。●分包情况下,包总和上限是 8m,单个包上限是 2m。注意: 这里说的包大小是构建后最终客户端下载的离线包的大小,非源码包大小,具体包大小以 全息检测 数据为准。最佳实践分包加载●使用 分包加载 是包大小优化效果最明显的手段,建议开发者按照功能和使用频率对小程序的页面进行分包,以实现用户在使用小程序进入不同的页面时,包的按需下载。●此外,使用分包加载时可以使用 分包预下载 进一步优化启动耗时。在使用 分包加载 后,虽然能够将小程序包体积缩小,但是当用户在首次进入分包页面时,需要等分包下载完成后才能进入页面,从而造成页面启动的延迟,影响用户的使用。因此,可以在使用 分包加载 时使用 分包预下载 进一步优化启动耗时。在使用分包加载中如果遇到一些问题,请参见 。总包优化小程序启动过程中下载的代码包是源码经过构建后的产物,构建的过程分两步:前端构建、资源拷贝。前端构建支付宝框架已进行了优化,只会打包到使用到的文件,也就是说没有使用的页面、没有使用的自定义组件、没有使用的依赖是不会打包到最终产物的。但是图片、音视频等静态资源是会全部拷贝到最终产物包,因此对于没有用到的静态资源建议进行删除。同时,对于较大尺寸图片建议查看 包内图片过大。包内图片过大说明代码包内的图片大小会影响包的整包大小,影响包下载耗时,进而影响整体启动耗时。标准单张图片大小建议不超过 100kb。最佳实践包内图片文件在打包时,会全部拷贝到最终的打包产物中,因此,这些静态资源文件会占用大量的包体积,从而影响启动耗时。因此,建议开发者通过以下操作进行性能优化:●代码包中建议仅放入一些体积较小的图标,而过大的图片、声音、视频等其他类型的资源尽量避免放入。对于这类过大的资源文件,建议从 cdn 渠道上传,且需要控制并发加载数量。建议使用雪碧图技术或在屏幕外的图片使用 懒加载,并开启 http 缓存控制。●及时清理没有使用到的图片。●合理压缩、剪裁图片大小。可以使用 等压缩工具进行压缩。●将图片格式转换 webp 或者 svg。webp 和 svg 格式的图片能够在不降低图片质量的前提下减小图片的体积,可以使用 等工具进行转换。网络图片网络请求图片过大说明网络请求图片过大会影响请求耗时,从而影响页面启动耗时,且消耗过多的网络流量,影响资源流耗。标准建议单张图片大小不超过 100kb。最佳实践●如果使用了 alicdn 服务,建议参考 相关能力进行处理。●将图片格式转换 webp 或者 svg。webp 和 svg 格式的图片能够在不降低图片质量的前提下减小图片的体积,可以使用 、adobephototshop 等工具进行转换。●合理压缩、剪裁图片大小。根据图片实际需要对图片进行合理压缩和剪裁:可以使用 、adobephototshop 等压缩工具进行压缩。●大图建议从 cdn 渠道上传,且需要控制并发加载数量,并开启 http 缓存,下次加载同样图片,直接从缓存读取。●较小的图片建议放到源码包中,避免不必要的小图片的请求耗时影响整体启动耗时。在以往的性能治理案例中,出现过将几 kb 的图片放到线上且没有使用 cdn,导致对启动耗时影响了 10%,这样的情况应该避免。图片并发请求过大说明短时间内发起太多图片请求会加重网络带宽压力,且并发请求太多也会导致图片加载慢。标准同域名耗时超过 300ms 的图片请求并发数不超过 6 个。最佳实践●首屏页面应降低业务的复杂度,减少图片请求的频率。●使用雪碧图来进行优化。css 雪碧图的基本原理是把一些小图标整合到一张单独的图片中,请求的时候只请求这个图片,在需要显示图标的地方,使用 css background 和 background-position 属性来进行定位。使用雪碧图可以减少 http 请求次数,提高页面加载速度。具体使用可以参考淘宝页面雪碧图的使用: ●图片开启 http 缓存控制,下次加载同样图片,直接从缓存读取。●未使用到的图片或者屏幕外的图片采用 懒加载 处理;具体优化方法查看 加载屏幕外图片。加载屏幕外图片说明加载当前屏幕中暂时不需要展示的图片,会影响页面加载耗时,增大内存消耗。标准屏幕外图片加载个数为 0。最佳实践建议分屏懒加载。代码示例启动阶段图片请求数过多说明小程序启动阶段网络请求的图片过多,一方面会耗费网络资源,导致网络通道拥挤,网络处理时长增加,另一方面不断加载的图片会导致页面不断重排、重绘引起页面不断抖动,推迟首次可交互的时间。尤其是线上很多小程序实际用户使用场景是非 wifi,容易出现网络不稳定的情况,比如健康码相关的小程序场景,因此此类场景下,如果图片请求过多会导致线上用户的启动耗时比较长。标准小程序启动阶段网络请求的图片小于 10 个。最佳实践●减少启动阶段的非必要图片请求。屏幕外的图片可以使用 懒加载,如果不确定,可以给所有图片都加上该属性,具体使用方法参考 加载屏幕外图片 里的最佳优化方案。●对于较小的图片,建议放到代码包里,或者使用雪碧图来减少图片请求数,雪碧图的使用可查看 图片并发请求过大。●图片开启 http 缓存控制,下次加载同样图片,直接从缓存读取,从而减少非首次访问的启动耗时。jsapi 接口调用同步 jsapi 调用次数过多说明同步的 jsapi 虽然开发比较方便,但是会有很大的性能损耗。具体表现在同步 jsapi 的调用过多将造成进程的阻塞,影响后续业务逻辑的执行,造成响应变慢,因此原则即是 能不用就不用,非要用要慎重 。优化经验中发现,getsysteminfosync、getstoragesync、setstoragesync、getlocation、getcities 是同步调用的高发区。标准应避免过度使用 sync 结尾的同步 api,同种 jsapi 同步执行次数应不超过 5 次。最佳实践●在小程序初始化代码和启动相关的几个生命周期 app.onlaunch 、app.onshow、page.onload、page.onshow、page.onready 中,应避免过度使用 sync 结尾的同步 api,同步执行转化成异步执行。下表为同步接口对应的异步接口:同步接口异步接口my.setstoragesyncmy.setstoragemy.getstoragesyncmy.getstoragemy.removestoragesyncmy.removestoragemy.clearstoragesyncmy.clearstoragemy.getstorageinfosyncmy.getstorageinfomy.getsysteminfosyncmy.getsysteminfomy.getbatteryinfosyncmy.getbatteryinfomy.getextconfigsyncmy.getextconfig●对于getsysteminfo、getsysteminfosync 、getextconfigsync、getextconfig这类的 jsapi,调用的结果应进行缓存,避免重复使用。比如通过 getsysteminfo 获取信息后可以用变量来做缓存,后续使用时直接使用变量即可。 示例代码:以 my.systeminfosync 为例。●对于 getstoragesync、setstoragesync 同步 jsapi 调用次数过多的情况:my.setstoragesync my.getstoragesync 设计目的是为给小程序提供类似于 前端 localstorage 即本地缓存的功能,并非是提供类似 redux/vuex 的全局状态管理的最佳实践。在开发过程中,建议合理使用这两个同步 jsapi,简单的状态管理可以使用 app.globaldata,复杂的使用 herculex 或跨端开发框架提供的状态管理。示例代码:使用 app.globaldata 来进行状态管理。●合并多个字段到一个对象,减少需要的次数。jsapi 重复调用次数检测说明jsapi 重复调用指的是 jsapi 名称和参数都相同的情况下,多次重复调用请求的情况,最常见的是多次网络请求 request 而其中 url 相同;首屏页面加载中,jsapi 多次重复调用会增加无用耗时,影响小程序整体的启动耗时。标准同种 jsapi 可重复调用次数应不超过 5 次。最佳实践●采用数据 缓存 方式处理前要执行 jsapi 后的结果数据,避免重复调用,对于 getsysteminfo、getsysteminfosync 获取信息后可以用变量来做缓存,后续使用时直接使用变量即可。●不要把 storage 相关 api 作为状态管理工具,可以把信息存在 app 实例上:●同步 jsapi 的优化可查看 同步 jsapi 调用次数过多。jsapi 并发检测说明jsapi 不是免费的,当调用 jsapi 时,底层的链路为:小程序调用 jsapi > 通知客户端(android、ios 支付宝客户端)执行对应的逻辑 > x ms 之后执行完毕 > 把结果返回给小程序 > 小程序回调;因此 jsapi 并发过高会导致客户端响应变慢、阻塞其他 jsapi 的响应(可能会阻塞其他业务逻辑)、用户耗电增加、请求超时等问题(例如网络通信吞吐量有限的情况下,部分请求会阻塞、超时,甚至直接以失败返回,影响业务)。标准jsapi 并发次数应不超过 20 次/s。最佳实践●采用数据 缓存 方式处理前要执行 jsapi 后的结果数据,减少调用次数。●减少并发执行次数。比如使用排队等策略,保障高优先级的业务请求。●同步 jsapi 的优化可查看 同步 jsapi 调用次数过多。setdatasetdata 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。setdata 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口。常见的 setdata 操作错误主要为频繁调用 setdata 、setdata 导致传递的数据量过大。setdata 数据量检测说明由 setdata 底层原理可知,由于逻辑层和视图层通信时,数据需要序列化,并通过 evaluatejavascript 执行脚本,因此,setdata 传递的数据量过大时,会影响首屏渲染性能。标准首屏页面单次 setdata 调用,传递的字符串数据量应不超过 256kb。最佳实践●减少数据量,避免一次性 setdata 传递过长的列表。●分批处理。首屏请勿一次性构造太多节点,服务端可能一次请求传递大量数据,请勿一次性 setdata,可先 setdata 一部分数据,然后等待一段时间(比如 400ms,具体需要业务调节)再调用 $splicedata 将其他数据传输过去。setdata 调用次数检测页面 setdata 调用次数不宜过多,否则会导致 js 线程一直在执行编译和渲染,视图层和逻辑层数据交互阻塞,可能导致用户的事件操作传递到逻辑层不及时,同时逻辑层的处理结果也不能很快的传递到视图层,从而造成用户滑动时的卡顿和操作反馈延时。标准页面 setdata 调用次数应不超过 20 次/s。最佳实践●页面级别或组件级别避免频繁触发 setdata 或者 $splicedata。在分析的案例中,有些页面存在倒计时逻辑且过于频繁触发(ms 级别的触发)。●需要频繁触发重新渲染时,避免使用页面级别的 setdata 和 $splicedata, 将这一块封装成自定义组件,然后使用组件级别的 setdata 或 $splicedata 触发组件重新渲染。●使用 $batchedupdates 合并多次 setdata 请求为一次 setdata,进而减少逻辑层到视图层的更新次数。 注意:只会合并方法中同步的 setdata 调用。网络请求网络请求耗时检测说明单次网络请求(如 http),从发起请求到数据返回的耗时,网络请求耗时过长将导致数据等待,延迟首屏初次渲染开始的时间,会让用户一直等待甚至离开。标准单次网络请求耗时时长不超过 400ms。最佳实践●数据缓存存储网络请求结果。支付宝提供 my.setstorage / my.getstorage 等异步读写本地缓存的能力,将数据存储在本地,返回结果的速度会比网络请求快。对于部分网络请求数据,可优先从缓存中获取数据来渲染视图,等待网络请求返回后进行更新。●避免重复请求。在过去案例中常见同一 url 发起多次网络请求 request。●优化好服务器处理时间。服务端可做 cdn 缓存,做网络请求的预加载(预热),让前端请求能快速响应。●页面资源的域名尽量采用相同域名。底层网络可以复用相同的 tcp 连接做资源请求,节省了重复的 dns > tcp 建连 > https 握手等繁杂的网络交互工作,这样可以大幅提升资源加载效率。●页面资源依赖切勿依赖国外站点,例如:。跨国访问普遍比较慢,应该将国外站点资源发布到自己的服务器,可以大幅提升网页打开的性能。●非关键资源应该做好隔离。避免非关键资源加载过慢,导致整个页面渲染不出来。●http 请求长耗时服务器设计。如果服务器处理时间较长,需要 10s 才能返回结果的情况,必须设计为可轮询查状态的模式,切勿一个 http 请求上去等 10s 的 response,很容易触发 socket 读超时导致业务失败。而且移动网络也不够稳定,中间如果出现网络抖动导致断链业务就会失败, 所以客户端可以采取间断性轮询请求服务器的方式去查服务器处理结果。网络请求 url 长度过长说明小程序网络请求的链路: my.request 请求 <-> 支付宝网络库 <-> 外部网络环境(wifi 3g4g)<-> 服务端。 url 过长会导致以下两种情况:●小程序发送给服务端的数据包过大,会延长数据传输时长和处理时长,最终影响小程序启动耗时。●支付宝网络库处理异常(支付宝客户端限制 url 长度)、服务端处理异常(服务端对 url 长度限制),进而导致请求失败。因此我们建议如非必要,减少 url 长度。标准网络请求 url 长度应不超过 2000 个字符。最佳实践●针对以上的第一种情况,建议将get 请求转换成 post 请求;但需要注意的是,这样的方式并不能解决第二种情况里数据包过大的问题。另外,在采用凯发app官方网站的解决方案时,开发者需要验证服务端是否支持这种请求类型;支付宝小程序转 post 请求的示例如下:●针对数据包过大的第二种情况,建议对数据进行合理拆分,分页、分级请求和展示,从而减少 url 的长度。工具说明针对上述可优化的点,支付宝推出 全息检测 工具进行检测,以帮助开发者进行检测和分析、优化。支持 ide 为 2.0 以上版本,可通过 ide 下载凯发app官方网站官网 进行升级下载。