• 开发教程与代码示例
  • 入门
  • 小程序框架
  • 小程序运行时
  • 自定义组件
  • 基础教程
  • 能力教程
  • 性能优化
  • 概述
  • 性能优化辅助平台/工具
  • 性能优化方法
  • 启动性能
  • 小程序启动流程
  • 小程序启动性能优化
  • 启动耗时优化
  • 启动打开率优化
  • 启动性能优化指引
  • 概述
  • 运行时性能
  • 小程序白屏&渲染异常问题优化
  • 安全
  • 小程序启动是小程序用户体验中极为重要的一环,启动耗时过长直接影响用户体验,从而造成小程序用户流失。
    小程序的启动过程从「用户打开小程序」到小程序「首页渲染完成」。「用户打开小程序」有多种方式,可以通过扫码、小程序跳小程序或从 App 打开小程序等入口触发。小程序「首页渲染完成」的标志是首个页面 Page.onReady 触发。由于启动流程的差异,小程序定义的「首页渲染完成」不等同于浏览器的DOMContentLoadedload 事件。
    结合《小程序启动流程》接下来我们针对启动中的关键环节给出针对性的建议。

    减小包体积

    小程序的首屏载入长短是用户使用小程序的重要体验指标之一,而代码包的大小则会直接影响了小程序启动时的下载耗时,对首屏载入有着举足轻重的影响。
    关于包体积标准的定义:
      1.不包含分包时,项目整体包体积上限为 16M 。
      2.包含分包时,主包体积上限为 4M,单个分包体积上限为 2M,项目整体包体积上限为 16M。
    以下为常用的三种包体积优化的方法:

    项目内容分包

    对于所有类型的小程序而言,使用分包加载是优化小程序启动耗时最有效的方法。建议开发者按照功能模块,将小程序的页面按使用频率和场景拆分成不同分包,实现用户在使用小程序时,不同页面的代码包按需加载。但是同时也需要合理控制分包数量,过多的分包会造成更多的下载,带来负面影响
    分包加载具有以下优势:
      承载更多功能。小程序单个代码包的体积上限为 2M,使用分包可以提升小程序代码包总体积上限,承载更多的功能与服务
      降低代码包下载耗时。有效分包后可以显著减少启动或页面切换时需要下载的代码包,在不影响功能的前提下明显降低启动耗时
      降低开发者代码注入耗时。小程序启动时会一次性注入全部的开发者代码,使用分包后可以降低注入的代码量,从而降低注入耗时
    除此以外,以下方法还可以进一步优化小程序启动耗时:
    在复杂且相对独立的场景中,如广告页、活动页、支付页等,通常功能不是很复杂且相对独立,对启动性能有很高的要求,开发者还可以考虑合理使用 独立分包的方法 。按照设计,独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。所以,当用户从独立分包中页面进入小程序时,不需要下载主包,可以节约启动时间。因此推荐开发者可以按需将具有一定功能独立性的页面配置到独立分包中。
    在使用【分包加载】后,虽然能够有效减小小程序主包体积,提高首屏加载效率,但是当用户在首次进入分包页面时,仍然需要等分包内容下载完成后才能进入页面,从而可能造成页面跳转的延迟,影响用户的使用。因此,推荐按需使用分包并搭配使用 分包预下载 来进一步优化使用体验

    优化资源文件

    小程序项目中免不了使用图片、音频、视频、字体等资源文件,这些资源文件通常难以被进一步的压缩,因此会占用较多代码包体积,对于下载耗时的影响比代码文件大得多。
    根据开发实践经验,建议开发者:
      1.对于不需要透明格式的图片,推荐采用 jpeg 格式来代替 png 格式。同时使用适当的压缩工具对图片进行压缩,如 pngquant-bin 或者 mozjpeg
      2.TTSS 、 TTML 等文件中,尽量避免使用 base64 内联过多、过大的图片等资源文件,建议把这些图资源文件通过外链的方式引入。
      3.音频、视频、字体等资源文件的压缩有限,建议尽量避免放到代码包中,或部署到 CDN ,通过外链方式使用。
      4.大图建议尽量避免放到代码包中,或部署到 CDN 且启用并发加载数量控制,启用 HTTP 缓存功能,下次加载同样路径的图片,将直接从缓存读取,不再消耗网络带宽。
      5.较小的图片(例如小于 10KB)建议直接放到代码包中或整合成雪碧图,避免不必要的小图片的请求耗时影响小程序启动耗时。
      6.开启图片懒加载,设置 lazy-load 属性,避免屏外图片的请求影响小程序启动耗时。

    清理无用内容

    除了工具默认忽略的文件外,小程序打包会将工程目录下所有文件都打入代码包内。推荐开发者定时对下列类别的内容进行清理,以降低代码包体积:
      1.在开发阶段意外引入的第三方库;
      2.版本迭代升级废弃的老旧代码或无效依赖;
      3.与线上产品环境无关的测试代码;
      4.声明但未使用的组件、插件、扩展库。
    在使用三方框架或者打包工具(如、 Webpack、Rollup 等)对小程序代码进行预处理时,可以利用框架、工具提供的 tree-shaking 等特性去除冗余代码。同时,也要注意避免在预处理阶段时引入不必要的库和依赖。

    减少同步逻辑

    逻辑线层 initData(初始数据) 发送给视图线层后,视图线层才能开始进行渲染页面的工作。如果 initData 发送过晚,会导致渲染页面流程滞后。为了保证启动速度,开发者应该尽可能减小加载小程序代码包到发送 initData 过程的耗时。具体有以下手段:
      避免启动时运行过多同步代码。启动流程中,会注入开发者代码并顺序同步执行App.onLaunch,App.onShowPage.onLoad, 因此在这些前置的生命周期中应该减少使用同步 API 及过多的同步逻辑。
      延迟处理启动时不强依赖的逻辑,比如在页面 onready 之后执行。
      与渲染数据无关逻辑优先使用异步 API。
      减少启动过程中无用代码的加载。对于启动过程中使用不到的 JS, 可以先不加载,在真正需要使用时再去加载。
      充分利用缓存。对调用频次高的方法的结果进行缓存,例如
      getSystemInfoSync 调用较为频繁,可根据文档对于可启用缓存的地方,启用缓存。
      其他同步 API 调用频繁:
      替换为同类型异步API 调用方式
      利用 tt.setStorage 在本地缓存调用结果,避免重复调用。

    更早的展示首屏数据

      尽早调用关键 API 和请求。主页面数据通常来自服务端,逻辑层拿到主页面数据setData 后,视图层收到主页面数据后进行页面更新,得到 LCP。为了保证 LCP 的速度, 开发者应该尽可能早地请求,拿到页面数据并 setData
      接入数据预取。数据预取能够显著的减少网络请求时间,以西瓜视频小程序为例,线上 FMP 从 1173ms 优化到 818ms,整体优化 300+ms,速度提升了 30%,优化效果很明显
      避免非必要的 reLaunch,尽可能保证页面的及时展示
      缓存请求数据。小程序提供了 tt.getStoragett.setStorage 等读写本地缓存的能力,数据存储在本地,返回的会比网络请求快。如果开发者基于某些原因无法采用数据预拉取,我们推荐优先从缓存中获取数据来渲染视图,等待网络请求返回后进行更新

    图片优化

    图片加载过慢可能导致页面部分白屏,推荐以下手段进行优化。
      使用 CDN 并开启图片缓存。开启 HTTP 缓存控制后,下一次加载同样的图片,会直接从缓存读取,大大提升图片加载速度
      进行合理的压缩。图片过大会延迟页面的完全渲染
      选择合适的图片格式。对于不需要透明格式的图片,推荐采用 jpeg 格式来代替 png 格式

    按需渲染

    渲染线程收到主页面数据后会进行页面更新,首屏渲染完成的时机和页面的结构有很大的关系。为了保证启动的速度,开发者应该尽可能地降低渲染时长。具体有以下优化手段:
      延迟渲染首屏可视区域之外的区域。开发者可以将首屏可视区域外的页面进行懒加载,滑动到可视区域后再加载
      使用框架骨架屏,减少等待焦虑。通过小程序框架提供骨架屏机制,能比业务中创建的骨架屏加载时机更靠前,使用这一机制,可以减少用户的白屏等待时长,给用户带来更好的体验
      使用占位组件。在页面中渲染完成前通过占位组件替代组件进行渲染,在该组件注入后再将占位组件替换,从而降低复杂组件对页面加载的影响
    通过以上几个方面的优化方向,我们可以在一定程度上提升小程序启动性能。运行时优化可参考文档小程序运行时性能优化。开发过程中也可以使用体验评分工具来检测更多的小程序性能问题。

    避免渲染耗时长

    开发者工具 4.2.3 及以上版本 trace 工具来看:
      用trace工具,查看页面渲染过程中的 setData 操作及耗时,如果耗时确实较长稳定 > 50ms 或以上。
      看对应的data是什么,具体影响到哪些节点的渲染,是否包含非必要的渲染操作(被隐藏的不可见元素 / 页面可见区域之外的元素)。
      延迟展示区域外的元素和发送相关data,比如在重要区域(可是区域占比较大或较重要) setData callback 中再展示该部分。
      去除完全被隐藏的元素节点,并避免发送相关data。
      setData 频率较高的区域抽离为自定义组件,避免局部更新导致页面重渲染。

    短剧行业优化

    短剧类小程序有以下优化方案能高效降低启播耗时和冷启动耗时,建议接入。
      1.如果启动页面是视频播放页面,建议在锚点 schema 配置中加上剧集 ID,query 名为 tt_album_idtt_episode_id,query 取值为剧集 ID,能够提升小程序框架侧的优化命中率,降低启动耗时和视频启播耗时。
      2.极智超清转码和 H.265:转码接入流程指南。实现抖音同款清晰度,显著节省带宽成本并优化用户体验,提升用户时长。
      a.极智超清转码:基于主观视觉优化的智能编解码算法,同等等主观画质的前提下实现码率和带宽的极致压缩。
      b.H.265:一种较 H.264 更高效的编码格式,支持自动回退保障播放兼容性,设备不支持 H.265 协议时自动降级到 H.264 资源,保障播放兼容性;
    接入成本:无需开发,控制台验证后一键操作接入。
    接入收益
      1.有效节省带宽成本:「极智超清 H.265」文件大小可减少 20-40%。
      2.显著优化用户体验,提升用户时长:业务 A/B 实验数据,播放失败率-28%,卡顿率下降30%。

    非短剧行业-视频优化

    现在播放器的启播耗时也会被纳入 LCP 的计算,优化启播耗时和冷启动耗时有以下建议:
    当前页 / 启动页优化:
    视频渲染前(src 设置前)使用 tt.prerenderVideott.preloadVideo,优化目标资源加载。
      1.调用时机:越早越好,可在 onlaunch。
      2.使用限制:建议只优化一个资源,多次调用可能导致资源抢占影响效果。
      3.如果视频资源依赖网络请求,可以将该网络请求配置数据预取,减少请求耗时。
    次页优化 / 翻页场景:
    当前视频加载进度 10% 时,也可以对用户可能播放的下一集进行预加载 or 预渲染(调用上述 API)。

    避免启动后立即跳转页面

    请根据业务场景优化:
      1.启动页面下线,需要启动时重定向到其他页面
      a.不处理也可以,框架默认会重定向到首页(默认行为性能较好)。
      b.必须重定向到目标页面:可以使用框架提供的钩子监听和路由,但要避免多次重定向 App.onPageNotFound
      2.业务需求,设计如此
      a.启动后立即路由一定会影响启动耗时,这块对业务上有明确收益么,尽量避免此类实现。
      b.如果无法改造,可以参考以下建议,降低影响
      接入数据预取时,可以将目标页面的重要请求配置在启动页面(即启动schema 中的 startPage)对应的value 中。目标页面使用预取后的数据。也能够实现在启动时提前发起请求,优化启动性能。假如启动页A,实际启动后落地页B ,则数据预取配置如下
    { 页面B: { // 页面B的重要请求 } }