性能优化丨超高性价比性能优化方案:数据预取
1209 浏览2024年08月28日作者:抖音开放平台团队

关注专题不迷路,进入“开发技术新风向”专题首页,点击“关注”即可

更多视频版本请前往学堂收看《如何用性能分解读小程序》


一、什么是数据预取

数据预取能够在小程序冷启动时提前发起请求,并缓存请求内容,在真实请求时使用缓存数据,减少网络请求的时间。在一些发起网络请求较晚的场景,增加数据预取,可以提升页面完全展现的速度

  • 数据预取优势说明:

是否有预取

请求时机

备注

没有预取

启动后串行发起请求

网络请求会较晚

有预取

启动时并行发起请求

尽可能将请求时间提前

  • 预取注意事项:

预取只是一个提取执行请求的附加优化方案,预取逻辑和小程序启动逻辑是并行启动的,在正常接入数据预取并且能够命中缓存的情况下,不会对服务器造成额外负担。

标题

二级标题

内容

预取KEY

不带参数

id和url不带query部分相同时认为是同一个请求

不带参数,id相同

非预取发起的两个请求url如果不带query部分和 + id参数都相同时,也认为是同一个请求,如果传了usePrefetchCache,第二次请求会命中第一次的缓存

更新缓存

usePrefetchCache为false

只传入id,usePrefetchCache不传入或者未false时,会更新缓存。

有效期

缓存有效期为5min,app重启后销毁。

性能

重复请求

预取的请求和小程序实际的请求一致,否则会引入额外请求

LCP后的请求

只预取LCP前的关键请求,否则性能可能会恶劣

JS文件大小

尽量减少prelaunch.js的体积,建议小于10k

其他

-

需要保证prelaunch.js未执行会或者执行失败时,逻辑能正常运行

二、新、老方案的区别是什么

老方案指的是配置方案,可以通过配置的方式配置预取的内容。

但是当逻辑比较复杂,比如需要登录之后再预取,那配置方案就无法实现了。此时就有了可以通过js代码来编写预取的方式。

-

配置方案

新方案(JS方案)

原理

通过json配置,客户端解析配置处理

独立js环境,开发者通过js控制要执行的逻辑

能力


  • json配置限制,只支持几个固定数据源参数并行请求,复杂参数以及串行场景受限。
  • 支持能力少,只支持接口预取
  • 所有的逻辑均为开发者控制,灵活性高。
  • 支持能力多,支持图片请求等更多能力

接入成本

略高,整体链路对开发者黑盒,不便调试

低,便于调试,支持打印log

适用场景

参数简单,n个独立请求的简单场景。

配置方案不满足的复杂场景

三、详细使用教程:

开始前,下载最新版本 IDE 调试工具(4.2.4 或以上版本)

Web 页面 LCP 的优秀值为 2500ms,为减少因为性能问题导致的用户流失,我们目标设置为 2000ms

第一步:明确优化页面目标

选取PV较高的作为重点优化对象(不确定的可以通过「控制台-数据-数据中心-页面分析」模块查看)。

将PV 较高的页面设置为启动页面(如右图),然后进行第二步。

第二步:找出影响启动 / 页面切换耗时的主要影响元素

1、在IDE 中使用“体验评分工具” 勾选真机体验后,运行待整个页面渲染完成,点击屏幕后停止(点击屏幕是为了触发LCP 上报)。

2、查看体验评分结果(右图),截图部分为当前场景的最大元素,就是主要优化对象

3、找到主要优化目标:

    • 目标一:影响该部分渲染的数据请求(数据来源 、展示时机等),为主要优化接口,进行第三步「预取主要接口」。
    • 目标二:如果该区域有图片资源,且资源url 固定(如背景图等),则需要重点优化图片,同时根据 「数据预取JS方案」用 tt.preloadImages 预取图片资源。如果图片依赖网络请求,进行第三步。

第三步:预取主要数据接口

1、优化思路:尽可能前置主要元素的渲染时机

2、预取逻辑:

    • 根据上述流程找到 LCP 触发元素(上右图 已经圈⭕️出来了!),如果是图片,直接预取该图片。
      • 点击「查看详情」(下左图)展开渲染层,可以看到图片渲染时机。
    • 点击「查看详情」展开网络层,找到影响 LCP 元素的网络请求,选中看url 信息确认是不是LCP元素的数据源。
    • 找到重要请求后,尽可能前置请求发出的时机,依次检查以下几点:
      • 有前置依赖请求:对前置依赖配置预取,否则直接预取该请求,参考接入示例代码
      • 请求发起时机较晚(trace中请求前有其他逻辑或在 onload 之后):尽早早早发出该请求,并及时更新数据
      • 有前置同步 API:尽可能替换为异步API,或者放在请求后。

四、常见问题:

(1)业务接口依赖 tt.login 无法直接预取

新的数据预取方案 prelaunch.js 支持 tt.login 等API,具体支持范围见数据预取js方案-预取环境中支持的API。如有其他需求,可以直接通过社区、开发者助手等方式反馈。


(2)业务接口参数需要 md5 签名

使用三方框架开发的小程序, prelaunch.js 因为不支持原生打包,所以普通开发者如果使用到crypto-js时不知道如何处理。这里暂时提供一段精简后的crypto-js代码(只包含md5 / HmacMD5,core),详情请查看:数据预取js方案


(3)业务接口依赖启动场景值

新的预取方案支持在 prelaunch.js 中调用 tt.getLaunchOptionsSync,可以通过该API 直接获取启动参数。


(4)部分场景不希望命中预取结果

数据预取js方案中,本次请求不命中预取结果,可以将 usePrefetchCache 设置为 false, 或者调整 id 为未预取过的请求。

示例场景:希望详情接口只在页面A 使用缓存,其他页面发起请求时不希望命中预取。

示例建议:配置预取时,id 命名为 ${字符串}_${页面path} 作为标识。


(5)预取了很多接口,为什么优化不明显

数据预取的接口或图片并不是越多越好,目标是将重点请求接入预取(如LCP 的触发元素或其来源请求)

数据预取只是将请求前置,预取时发起过多请求也会有资源竞争,可能导致预取耗时过长,预取结果命中率降低。

建议接入个数:1~3 个(接口 或 图片数量,分开计数);

分析步骤:见启动性能优化指引


(6)数据预取的请求会阻塞后面的请求吗? 相同的请求,如果预取没有请求完毕,会发起两遍吗

数据预取不会阻塞,是并行的状态,后续相同的请求,会使用之前请求的结果。

不会发起两遍,如果调用 tt.request 时请求时传入的 id 参数相同,那么第二个请求不会发起网络请求,会直接复用第一次请求。


(7)prelaunch.js 执行时机是什么时候,和请求前置到 onLaunch 效果一样么

prelaunch 效果更好,onLaunch 阶段任务更多,API 调用可能会被阻塞,prelaunch 的执行是在一个独立的线程,效率更高。


(8)数据预取链接失败,捞日志发现timeout

可能原因有:

手机和电脑不在同一个局域网。

电脑打开了防火墙,导致手机无法访问,关闭后正常,可以在手机上直接访问 ip:7047 看是否能通。


(9)如何在 prelaunch.js 中使用环境变量

可以通过字符串替换的方式来注入环境变量


(10)「registerOnPrelaunch 的回调在小程序生命周期只会触发一次」,启动页面A 和 app 都注册了,两个回调都会触发吗?

通过 registerOnPrelaunch 注册的 app 和 特定页面的回调,都会执行, app 先执行。


(11)数据预取js 方案和配置方案可以一起使用么

不建议一起用,两者效果相同,只保留一种就可以。因为数据预取js 方案是一个独立的 worker 环境,请求链路无法复用,两个预取请求都会发出,导致不必要的资源浪费。

最后一次编辑于 2026 年 03 月 11 日
0 条评论

相关公告

专题推荐

热门文章

热门问答