在 React Native SDK 中优化流程与付费墙的加载
在 React Native 中实现可靠的流程或付费墙加载需要做到三点:渲染速度快、返回针对目标受众的实验变体,以及在网络较慢时能优雅地降级处理。以下规则涵盖了实现这些目标所需的时机控制、缓存和备用方案。
以下规则假设 adapty.activate() 和 adapty.identify() 已执行完毕。详见 React Native SDK 的调用顺序。
规则与注意事项
| 这样做 | 不要这样做 | 原因 |
|---|---|---|
获取即将展示的版位,或使用 preloadFlows(SDK 4.3.0+)预热缓存。 | 在启动时自行发起并发的 getFlow 调用。 | 手动批量预取会阻塞 JS 线程并产生黑屏。preloadFlows 专为此场景设计,一次调用即可将批次请求发送给原生 SDK。 |
在归因有机会完成解析后再调用 getFlow——例如在 activate 后 1–2 秒,或在 onLatestProfileLoad 触发后。 | 在根组件挂载时调用 getFlow。 | 归因数据尚未到位。流程会按默认目标受众进行解析,静默跳过市场细分和 ASA 个性化设置。 |
设置 loadTimeoutMs 并为每个版位配置备用付费墙。 | 无限等待 getFlow。 | 没有超时设置,网络较差的用户会看到空白屏幕,直到网络恢复——或者直接退出应用。 |
请参阅获取自定义付费墙和产品了解 fetchPolicy 和 loadTimeoutMs 参数说明,以及版位了解如何选择合适的版位。
预加载版位
preloadFlows 和 preloadFlowsForDefaultAudience 从 SDK 4.3.0 版本起可用。
preloadFlows 会提前缓存流程 JSON——每个版位发送一次请求。之后按常规使用即可:用 getFlow 获取流程,用 createFlowView 创建其视图。
fetchPolicy 决定后续 getFlow 优先从哪一层读取数据,而不是决定是否能访问缓存:
'return_cache_data_else_load'会优先读取预加载的缓存副本,仅在没有缓存时才请求网络。'return_cache_data_if_not_expired_else_load'的逻辑相同,但仅在副本未超过maxAgeSeconds时使用缓存。- 默认策略
'reload_revalidating_cache_data'优先请求网络,当请求失败或超时时回退到预加载的副本。
预加载在两种策略下都能发挥作用,只是方式不同:缓存优先策略会直接省去网络请求,而默认策略则保留请求,并在请求失败时获益于已预热的副本。
当你已知本次会话需要哪些版位、但暂时不想显示时,可以使用此方法——例如,在 activate 和 identify 完成后立即预加载,用于用户尚未点击的按钮背后的流程。
try {
await adapty.preloadFlows(['onboarding', 'main_paywall'], {
loadTimeoutMs: 5000,
});
} catch (error) {
// at least one placement failed to preload
}
// Later, when the user reaches the paywall:
const flow = await adapty.getFlow('main_paywall', {
fetchPolicy: 'return_cache_data_else_load',
});
参数:
placementIds(必填):要预加载的版位。loadTimeoutMs(可选):超时时间,单位为毫秒。默认值为 5000,低于 1000 的值将被提升至 1000。在 iOS 上,超时适用于整个批次;在 Android 上,超时适用于每个版位。
需要了解的行为:
- 只有在所有版位均尝试完毕后,Promise 才会拒绝,且错误会聚合各版位的失败信息。某个版位的失败不会影响其他版位,已成功加载的版位仍会保留在缓存中。
- 如果某个版位超时或发生网络错误,SDK 会回退到该版位的默认目标受众变体。其他类型的失败则按原样上报。
- 预加载仅用于预热缓存,不返回内容——你仍需调用
getFlow来显示内容。
预加载涵盖的内容
流程到达屏幕分为多个层级。预加载负责第一层,与 getFlow 的作用完全相同:
| 层级 | 由谁获取 | 预加载是否预热 |
|---|---|---|
| 流程 JSON — 选中的实验变体、其产品 ID 及远程配置 | getFlow | 是 |
| UI 布局 — 屏幕的结构、样式与文字 | createFlowView | 否 |
| 图片,包括视频元素的占位静帧 | createFlowView,在后台执行 | 否 |
| 视频文件 | 系统播放器,在屏幕渲染时加载 | SDK 不缓存 |
因此,对于给定布局,首次调用 createFlowView 在预加载之后仍然需要一次网络往返。此后,原生 SDK 会将该布局保存到磁盘缓存中,且缓存在应用重启后依然有效,因此开销只发生在第一次请求时,而非每次请求都会产生。
跳过目标受众细分
如需在完全不等待目标受众细分的情况下预热缓存,请使用默认目标受众实验变体。该方式无需超时设置:
await adapty.preloadFlowsForDefaultAudience(['main_paywall']);
从应用包中显示第一屏媒体
流程会从 Adapty 下载图片和视频。若要让第一屏媒体立即显示,可改为从应用包中提供。这是复用应用内已有媒体资源的好方式,例如现有原生用户引导的视觉素材。
- 在流程与付费墙编辑工具中,为图片或视频设置自定义媒体 ID。上传的文件将作为备用文件。
- 将文件添加到原生项目中:iOS 的 app bundle 和 Android 的
assets文件夹。 - 创建流程视图时,在
customAssets中为该 ID 传入打包的文件:
// "welcome_video" is the custom media ID set in the Flow & Paywall Builder
const bundledAssets: Record<string, AdaptyCustomAsset> = {
'welcome_video': {
type: 'video',
fileLocation: {
ios: { fileName: 'welcome.mp4' },
android: { relativeAssetPath: 'videos/welcome.mp4' },
},
},
};
const view = await createFlowView(flow, { customAssets: bundledAssets });
捆绑文件会增加应用的下载体积,因此只捆绑用户首先看到的媒体资源。
未捆绑的媒体文件同样会即时呈现:流程布局中包含每张图片(含视频静帧)的低分辨率缩略图,并在完整文件加载完成前持续显示。
完整的 customAssets 参考,请参阅自定义资源。
针对弱网环境进行优化
针对网络连接持续较差的市场(农村地区、交通路线、受路由问题影响的地区):
- 除第一次请求外,所有请求都设置
fetchPolicy: 'return_cache_data_else_load'。 - 在 Adapty 看板中为每个版位配置备用付费墙。
- 将
loadTimeoutMs设置为 3–5 秒,并在超时触发时接受备用付费墙。 - 不要将流程显示的前提条件设置为
getProfile()。独立调用getFlow,避免因获取用户画像较慢而阻塞 UI。