小程序 callContainer 预取接入手册
收藏
我的收藏背景
callContainer 支持小程序端访问部署在抖音云上的云服务,目前已对齐 tt.request 的 js 预取方案,在小程序冷启动时提前发起请求,提升首页渲染速度。
收益
预计可优化首屏 LCP 约 100 ms。
方案影响
预取只是一个提取执行请求的附加优化方案,预取逻辑和小程序启动逻辑是并行启动的,在正常接入数据预取并且能够命中缓存的情况下,不会对服务器造成额外负担。因此需要注意预取的请求和小程序实际的请求一致,否则会引入额外请求。
代码接入
prelaunch.js 文件
添加 callContainer 预取逻辑
// path 启动页路径 query 启动页参数 registerOnPrelaunch('xxx', callback: (params: { path: string, query: string }) => { const cloud = tt.createCloud({ envID: 'xxx', serviceID: 'xxx' }); cloud.callContainer({ path: 'xxx', id: "prefetch", usePrefetchCache: true, init: { method: 'GET', header: { 'content-type': 'application/json', }, timeout: 60000,//ms }, success: (data) => { console.log('callcontainer prelaunch index success callback', data); }, }); });
消费触发的 callContainer 预取缓存
const cloud = tt.createCloud({ envID: 'xxx', // 与 触发时 envID 相同, serviceID: 'xxx' // 与 触发时 serviceID 相同, }); cloud.callContainer({ path: 'xxx',// 与 触发时 path 不带 query 部分相同。 id: "prefetch", // 必须与触发时相同, usePrefetchCache: true, // 必须为true init: { method: 'GET', header: { 'content-type': 'application/json', }, timeout: 60000,//ms }, success: (data) => { console.log('callcontainer index success callback', data); }, });
callContainer 预取接入 demo
假设当前小程序启动页为 index 页面,需要对首页接口 /index 实现预取。可按照如下流程:
- 1.在 prelaunch.js 中注册 index 页面回调监听,并且在回调里发起 callContainer 请求,如下:
大前提得用 canIuse 判断 createCloud 和 callContainer 是否可用。
在 callContianer 需设置 path, id, usePrefetchCache 为 true。
// // 监听index页面,只有index页面冷启动才会执行 registerOnPrelaunch('pages/index/index', function () { if (tt.canIUse('createCloud')) { console.log('prelaunch中可用createCloud'); const cloud = tt.createCloud({ envID: 'xxx', serviceID: 'xxx' }); cloud.callContainer({ path: '/index?a=prelaunch', id: "prefetch", usePrefetchCache: true, init: { method: 'GET', header: { 'content-type': 'application/json', }, timeout: 60000,//ms }, success: (data) => { console.log('callcontainer prelaunch index success callback', data); }, }); } else { console.log('prelaunch.中不可用createCloud'); } });
- 2.在实际页面复用预取,在 index.js 页面写如下代码:
若想复用请求,需设置 serviceID, envID, path 不带query 部分,以及id 与 prelaunch.js 中相同,usePrefetchCache 为 true。
const app = getApp() let cloud; Page({ data: { imageSrc: "" }, onLoad: () => { if (tt.canIUse('createCloud')) { console.log('index.中可用createCloud'); const cloud = tt.createCloud({ envID: 'xxx', // 需设置 envID 与 prelaunch.js 中相同 serviceID: 'xxx' // 需设置 serviceID 与 prelaunch.js 中相同 }); cloud.callContainer({ path: '/index', // 需设置 path 不带 query 部分与 prelaunch.js 中相同 id: "prefetch", // 需设置与 prelaunch.js 中相同 usePrefetchCache: true,// 必须设置为 true init: { method: 'GET', header: { 'content-type': 'application/json', }, timeout: 60000,//ms }, success: (data) => { console.log('callcontainer index success callback', data); }, }); } else { console.log('index.中不可用createCloud'); } } });
- 3.查看结果:
实际页面中请求的 usePrefetch 为 true。表示命中预取。
在 IDE Network 中查看也仅发起了一次请求。
端上可用安卓机或者 iOS 真机调试查看,
客户端扫码预览调试可查看对应数据预取命中结果:
callContainer 实际请求中打印 isPrefetch 为 true, prefetchDetail 表示命中预取具体 code。预取返回值详情见:
属性名 | 类型 | 说明 | 最低支持版本 |
isPrefetch | boolean | 是否使用预取缓存 | 3.41.0 |
prefechDetail | number | 预取结果描述。其中-1为默认值;1~8为未匹配原因;9为没有任何缓存;22,23为已发起预取,但返回结果失败或返回结果为空;100为命中缓存;101为命中请求中缓存,并成功;102为命中请求中缓存,请求失败,为网络错误。 | 3.41.0 |
prefetchInfo | string| object | 数据预取的结果的详细信息 | 3.41.0 |
profile 为各网络阶段具体参数。
属性名 | 类型 | 说明 | 最低支持版本 |
domainLookupStart | number | DNS 域名查询开始的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 requestStart 值相等 | 3.41.0 |
domainLookupEnd | number | DNS 域名查询完成的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 requestStart 值相等 | 3.41.0 |
connectStart | number | HTTP(TCP) 开始建立连接的时间,如果是持久连接,则与 requestStart 值相等。注意如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接开始的时间 | 3.41.0 |
connectEnd | number | HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 requestStart 值相等。注意如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接完成的时间。注意这里握手结束,包括安全连接建立完成、SOCKS 授权通过 | 3.41.0 |
sslConnectionStart | number | SSL 建立连接的时间,如果不是安全连接,则值为 0 | 3.41.0 |
sslConnectionEnd | number | SSL 建立完成的时间,如果不是安全连接,则值为 0 | 3.41.0 |
requestStart | number | HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存。连接错误重连时,这里显示的也是新建立连接的时间 | 3.41.0 |
requestEnd | number | HTTP 请求读取真实文档结束的时间 | 3.41.0 |
rtt | number | 当次请求连接过程中实时 rtt | 3.41.0 |
estimateNetType | string | 评估的网络状态 unknown, offline, slow 2g, 2g, 3g, 4g, last/0, 1, 2, 3, 4, 5, 6 | 3.41.0 |
throughputKbps | number | 当前网络的实际下载 kbps | 3.41.0 |
port | number | 当前请求的端口 | 3.41.0 |
socketReused | boolean | 是否复用连接 | 3.41.0 |
sentBytesCount | number | 发送的字节数 | 3.41.0 |
receivedBytesCount | number | 收到的字节数 | 3.41.0 |
预取逻辑前接入必看
- 1.envID,serviceID, id 和 path 不带 query 部分相同时认为是同一个请求。id参数决定了请求是否能匹配,usePrefetchCache 参数决定是否要使用缓存。
- 2.非预取发起的两个请求 path 如果不带 query 部分和 + id 和其余 envID 参数都相同时,也认为是同一个请求,如果传了usePrefetchCache,第二次请求会命中第一次的缓存。
- 3.只传入id,usePrefetchCache不传入或者为 false 时,会更新缓存,缓存key 为 envID + serviceID + id + path 不带query。
现在有 callContianer path 为 a/?b=1 和 callContainer path 为 a/?b=2 两个请求(不区分是否是预取环境)
- •如果调用 callContainer 时请求时传入的id参数相同,那么第二个请求不会发起网络请求,会直接使用 path 为 a?b=1 的接口。
- •如果想让 callContainer path 为 a/?b=2 重新发起请求。要么:
- •不传 id/usePrefetchCache 不为true。
- •id参数生成逻辑把b这个query的值带上。
- 4.只预取 LCP 前的关键请求,否则性能可能会恶劣。
- 5.缓存有效期为5min,app重启后销毁。
- 6.需要保证 prelaunch.js 未执行会或者执行失败时,逻辑能正常运行。
- 7.尽量减少 prelaunch.js 的体积,建议小于10k。