数据预取配置方案示例
收藏
我的收藏确定预取对象
找出主要元素
下面介绍如何找出影响启动 / 页面切换耗时的主要影响元素
(1)在IDE 中使用“体验评分工具” 勾选真机体验后,运行待整个页面渲染完成,点击屏幕后停止。
(2)查看体验评分结果(右图),截图部分为当前场景的最大元素,也就是主要优化对象。
(3)找到主要优化目标
影响该部分渲染的数据请求(数据来源 / 展示时机等),为主要优化接口,进行下一步「1.2 确认预取接口」。
确认预取接口
相关请求可能有以下场景。
(1)场景一:无上下文依赖。直接将该接口按照预取方案配置即可
(2)场景二:有上下文依赖。
- 1.请求参数依赖其他接口返回值:例如页面渲染内容接口A 依赖 接口B 的返回值,无法直接配置接口B 的规则,则为接口A 配置预取规则即可。
- 2.请求参数依赖其他状态值:例如登陆态,授权态等。将动态值通过 tt.setStorage 或 tt.setStorageSync存储到本地,具体参考下述接入流程示例。
- 3.请求参数依赖部分API 动态调用结果:「数据预取新方案」。
- i.如根据登陆态请求不同接口,prelaunch.js 中也可以调用 JSAPI , 可以判断登陆后再走到预取请求逻辑
启动接入
示例场景
网络请求所在页面:
pages/index/index
具体场景:在启动时根据启动路径 pageid query 参数调用https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request/接口获取信息,在接口返回后根据接口返回内容展示页面内容。 如:
page/index/index?pageid=123
接口依赖:接口参数中依赖
token
, dataKey1
动态参数// app.js App({ onLaunch() { tt.setStorageSync('token', 'testToken') tt.setStorageSync('dataKey1', 'dataKey1Value') } }) // page/index/index.js Page({ onLoad(options){ tt.request({ url: `https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid={options.pageid}`, method: 'POST', header: { token: tt.getStorageSync('token'), }, data: { dataKey1: tt.getStorageSync('dataKey1'), dataKey2: 1 }, success: (res) => { console.log("请求数据:", res.data); }, }); } })
修改App.json
... { "prefetchRules": { // 需要配置预取请求的页面 "pages/index/index": { // 请求的url ,配置变量。变量从storage/启动参数上取同名字段。 "https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid}": { // 请求的方法 "method": "POST", // 请求的header "header": { //配置token变量 "token": "${token}" }, // POST请求的body数据 "data": { //配置dataKey1变量 "dataKey1": "${dataKey1}", "dataKey2": 1, // 用于演示匹配时忽略key。 "testDataKey": "xxx" }, } } } } ...
上述配置含义如下:
- 1.
app.json
的 prefetchRule
字段中配置了 key 为 pages/index/index
的 json。表示在pages/index/index
页面启动时,根据其配置执行预取。- 2.
pages/index/index
对应 value 为一个 json,其中 key 为https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid}的配置,表示请求其配置内容请求 https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid} 接口。- 3.在https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid} 以及其配置中,存在
${xx}
的语法。可包含以下取值场景- a.标识从 storage 中由同名key的值填充请求配置。(在请求前通过 tt.setStorageSync 设置)
- b.启动 query 中由同名key的值填充请求配置。(启动参数中携带即可,无需其他操作)
- 4.到此已经完成请求的发起,后续将介绍如何消费提前发起的请求。可以通过控制台查看是否发起两次请求。
使用预取数据
usePrefetchCache 标识使用预取
tt.request
usePrefetchCache
参数标识使用预取的返回值,不传递则会重新发起请求。// page/index/index.js Page({ onLoad(options){ tt.request({ url: `https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid={options.pageid}`, method: 'POST', header: { token: tt.getStorageSync('token'), }, data: { dataKey1: tt.getStorageSync('dataKey1'), dataKey2: 1 }, // 配置此字段标识要使用预取的返回值。 usePrefetchCache: true, success: (res) => { console.log("请求数据:", res.data); }, }); } })
- 1.查看控制台
tt.request
的返回值,可以看到,仍然发起了两次网络请求,发现没有命中数据预取。- 2.为什么没命中???,请看下一步的匹配流程
修改 App.json 匹配逻辑
对于框架来说,无法预测预取配置的返回值能否被后续使用。因此由如下两种策略控制是否匹配
(1)完全匹配:只有预取的参数和tt.request的请求参数完全一致才能命中预取的返回值。
(2)模糊匹配:配置了hitPrefetchExtraRules 模糊匹配,标识哪些字段一致时即可匹配。推荐开发者使用此策略。
接下来,我们在
app.json
中添加匹配逻辑。- 1.data 中 dataKey1 和 dataKey2 参数影响接口返回值,testDataKey参数不影响接口返回值。在这种情况下,我们采用模糊匹配能力。即在hitPrefetchExtraRules的requiredDataKeys配置["dataKey1", "dataKey2"]。标识只需要这两个参数来影响数据预取是否能匹配。
- 2.query和header此演示demo配置不涉及额外参数,此处不做过多解释。遇到匹配问题时,合理配置关键参数即可。
... { "prefetchRules": { // 需要配置预取请求的页面 "pages/index/index": { // 请求的url ,配置变量。变量从storage/启动参数上取同名字段。 "https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid}": { // 请求的方法 "method": "POST", // 请求的header "header": { //配置token变量 "token": "${token}" }, // POST请求的body数据 "data": { //配置dataKey1变量 "dataKey1": "${dataKey1}", "dataKey2": 1, // 用于演示匹配时忽略key。 "testDataKey": "xxx" }, // 返回结果的类型 "responseType": "text", // 配置模糊匹配规则,提高请求预取命中率。 "hitPrefetchExtraRules": { // 配置只要query中的pageid参数相同即可命中 "requiredQueryKeys": ["pageid"], // 只要请求header中以下key的value相等,则匹配成功 "requiredHeaderKeys": ["token"], // 只要请求data中以下key的value相等,则匹配成功 "requiredDataKeys": ["dataKey1", "dataKey2"] } } } } } ...
接入完成
查看方式:console.log 打印请求结果,在真机 vconsole 中查看。
(1)预取成功:可以看到此处控制台只发起了一次网络请求。并且 tt.request 的返回值 res.isPrefetch 为true,接入完成!
线上优化效果
完整代码
代码片段链接
启动路径。pages/index/index?pageid=123
// app.json ..... { "prefetchRules": { // 需要配置预取请求的页面 "pages/index/index": { // 请求的url ,配置变量。变量从storage/启动参数上取同名字段。 "https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid=${pageid}": { // 请求的方法 "method": "POST", // 请求的header "header": { //配置token变量 "token": "${token}" }, // POST请求的body数据 "data": { //配置dataKey1变量 "dataKey1": "${dataKey1}", "dataKey2": 1, // 用于演示匹配时忽略key。 "testDataKey": "xxx" }, // 返回结果的类型 "responseType": "text", // 配置模糊匹配规则,提高请求预取命中率。 "hitPrefetchExtraRules": { // 配置只要query中的pageid参数相同即可命中 "requiredQueryKeys": ["pageid"], // 只要请求header中以下key的value相等,则匹配成功 "requiredHeaderKeys": ["token"], // 只要请求data中以下key的value相等,则匹配成功 "requiredDataKeys": ["dataKey1", "dataKey2"] } } } } } ..... // js
// page/index/index.js Page({ onLoad(options){ tt.request({ url: `https://microapp.bytedance.com/miniprogram-demo/invoke/tma_demo_request?pageid={options.pageid}`, method: 'POST', header: { token: tt.getStorageSync('token'), }, data: { dataKey1: tt.getStorageSync('dataKey1'), dataKey2: 1 }, // 配置此字段标识要使用预取的返回值。 usePrefetchCache: true, success: (res) => { console.log("请求数据:", res.data); }, }); } })