Оптимизация загрузки флоу и пейволов в React Native SDK
Надёжная загрузка флоу или пейвола в React Native решает три задачи: быстрый рендеринг, возврат варианта, соответствующего аудитории, и корректный резервный сценарий при медленном интернете. Правила ниже охватывают тайминг, кэширование и паттерны резервного отображения.
Предполагается, что adapty.activate() и adapty.identify() уже выполнились. См. Порядок вызовов в React Native SDK.
Правила и подводные камни
| Делайте так | Не делайте так | Почему |
|---|---|---|
Загружайте конкретный плейсмент или прогревайте кеш с помощью preloadFlows (SDK 4.3.0+). | Самостоятельно запускайте параллельные вызовы getFlow при старте. | Самодельный prefetch-burst блокирует JS-поток и вызывает чёрный экран. preloadFlows создан для этой задачи и отправляет батч в нативный SDK одним вызовом. |
Вызывайте getFlow после того, как атрибуция успела разрешиться — например, через 1–2 секунды после activate или после срабатывания 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 — к каждому плейсменту отдельно.
Важные особенности поведения:
- Промис отклоняется только после того, как будут обработаны все плейсменты, а ошибка агрегирует сбои по каждому из них. Сбой одного плейсмента не останавливает остальные, и плейсменты, которые успешно загрузились, остаются в кеше.
- Если плейсмент превысил время ожидания или завершился с сетевой ошибкой, SDK использует вариацию аудитории по умолчанию для этого плейсмента. Остальные сбои передаются как есть.
- Предзагрузка только прогревает кеш. Она не возвращает контент — для отображения по-прежнему нужно вызвать
getFlow.
Что покрывает предзагрузка
Флоу появляется на экране послойно. Предзагрузка покрывает первый слой — точно так же, как getFlow:
| Слой | Загружается через | Прогревается предзагрузкой |
|---|---|---|
| Flow JSON — выбранный вариант, идентификаторы продуктов и Remote Config | getFlow | Да |
| UI-макет — структура экрана, стили и текст | createFlowView | Нет |
| Изображения, включая стоп-кадр вместо видеоэлемента | createFlowView, в фоне | Нет |
| Видеофайлы | Системный плеер, при рендеринге экрана | SDK не кэширует |
Таким образом, первый вызов createFlowView для конкретного лейаута всё равно требует одного сетевого запроса даже после предзагрузки. SDK затем сохраняет этот лейаут в своём дисковом кэше, который переживает перезапуски приложения, — так что расходы приходятся только на первый запрос, а не на каждый.
Пропуск сегментации аудитории
Чтобы прогреть кэш без ожидания сегментации аудитории, используйте вариант аудитории по умолчанию. Он не требует таймаута:
await adapty.preloadFlowsForDefaultAudience(['main_paywall']);
Показ медиа первого экрана из бандла приложения
Флоу загружает изображения и видео из Adapty. Чтобы медиа первого экрана отображалось мгновенно, раздавайте его из бандла приложения. Это удобно, если нужные ресурсы уже есть в приложении — например, визуалы существующего нативного онбординга.
- В Flow & Paywall Builder задайте пользовательский медиаидентификатор для изображения или видео. Файл, загруженный туда, остаётся как запасной вариант.
- Добавьте файл в нативные проекты: в бандл iOS-приложения и в папку
assetsAndroid. - При создании представления флоу передайте бандловый файл для этого идентификатора в
customAssets:
// "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независимо, чтобы медленный профиль не блокировал интерфейс.