小程序 callContainer 预取接入手册

收藏
我的收藏

背景

callContainer 支持小程序端访问部署在抖音云上的云服务,目前已对齐 tt.request 的 js 预取方案在小程序冷启动时提前发起请求,提升首页渲染速度。

收益

预计可优化首屏 LCP 约 100 ms。

方案影响

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

代码接入

prelaunch.js 文件

prelaunch.js 文件编写及 registerOnPrelaunch 的使用方法可参考「数据预取 js 方案-添加入口文件和在 prelaunch 中监听页面的启动模块」。

添加 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。