Tối ưu hóa việc tải flow & paywall trong React Native SDK
Một lần tải flow hoặc paywall đáng tin cậy trên React Native cần đảm bảo ba điều: hiển thị nhanh, trả về đúng biến thể theo đối tượng, và xử lý dự phòng hợp lý khi mạng chậm. Các quy tắc dưới đây bao gồm thời điểm tải, caching và các mẫu fallback để đạt được điều đó.
Các quy tắc này giả định rằng adapty.activate() và adapty.identify() đã được resolve xong. Xem Thứ tự gọi trong React Native SDK.
Quy tắc và những lỗi thường gặp
| Làm thế này | Không làm thế này | Lý do |
|---|---|---|
Fetch placement bạn sắp hiển thị, hoặc làm ấm cache bằng preloadFlows (SDK 4.3.0+). | Tự tạo các lệnh gọi getFlow đồng thời khi khởi động. | Một burst prefetch tự tay sẽ chặn JS thread và gây màn hình đen. preloadFlows được tạo ra cho việc này và gửi batch đến native SDK chỉ trong một lần gọi. |
Fetch getFlow sau khi attribution đã có cơ hội được xử lý — ví dụ, 1–2 giây sau activate hoặc sau khi onLatestProfileLoad được kích hoạt. | Gọi getFlow tại root component mount. | Attribution chưa được xác định. Flow sẽ được xử lý theo đối tượng mặc định và âm thầm bỏ qua các phân khúc và cá nhân hóa ASA. |
Đặt loadTimeoutMs và cấu hình paywall dự phòng cho mỗi placement. | Chờ getFlow vô thời hạn. | Nếu không có timeout, người dùng có kết nối kém sẽ thấy màn hình trống cho đến khi mạng phản hồi — hoặc đóng ứng dụng. |
Xem Tải paywall tùy chỉnh và sản phẩm để biết tham chiếu tham số fetchPolicy và loadTimeoutMs, và Placements để chọn placement phù hợp.
Tải trước các placement
preloadFlows và preloadFlowsForDefaultAudience khả dụng từ SDK phiên bản 4.3.0 trở lên.
preloadFlows lưu trữ JSON của flow vào bộ nhớ cache trước — mỗi placement một request. Sau đó bạn dùng như bình thường: getFlow để lấy flow, createFlowView để tạo view của nó.
fetchPolicy quyết định layer nào mà lệnh getFlow phía sau sẽ đọc trước, chứ không phải là liệu nó có thể truy cập cache hay không:
'return_cache_data_else_load'đọc bản đã tải trước tiên, chỉ gọi mạng khi không có cache.'return_cache_data_if_not_expired_else_load'hoạt động tương tự nhưng chỉ khi bản cache còn mới hơnmaxAgeSeconds.- Giá trị mặc định là
'reload_revalidating_cache_data', ưu tiên gọi mạng và chỉ dùng bản đã tải trước khi yêu cầu thất bại hoặc hết thời gian chờ.
Việc tải trước đều có lợi trong cả hai trường hợp, nhưng theo cách khác nhau: chính sách ưu tiên cache sẽ loại bỏ hoàn toàn yêu cầu mạng, còn chính sách mặc định vẫn gửi yêu cầu nhưng có thêm bản dự phòng đã được cache sẵn.
Sử dụng khi bạn biết trước những placement nào sẽ cần trong phiên nhưng chưa muốn hiển thị ngay — ví dụ, ngay sau khi activate và identify hoàn thành, cho flow đằng sau một nút mà người dùng chưa nhấn.
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',
});
Tham số:
placementIds(bắt buộc): các placement cần tải trước.loadTimeoutMs(tùy chọn): thời gian chờ tính bằng mili giây. Mặc định là 5000, và các giá trị dưới 1000 sẽ được nâng lên 1000. Trên iOS, thời gian chờ áp dụng cho toàn bộ batch; trên Android, áp dụng cho từng placement.
Một số lưu ý về cách hoạt động:
- Promise chỉ bị reject sau khi tất cả các placement đã được thử, và lỗi tổng hợp các failure theo từng placement. Lỗi ở một placement không dừng các placement khác, và những placement đã tải xong vẫn được lưu trong cache.
- Nếu một placement bị timeout hoặc lỗi mạng, SDK sẽ fallback về biến thể đối tượng mặc định cho placement đó. Các lỗi khác được báo cáo nguyên trạng.
- Preloading chỉ làm nóng cache. Nó không trả về nội dung — bạn vẫn cần gọi
getFlowđể hiển thị.
Những gì mà preload bao gồm
Một flow hiển thị lên màn hình theo từng lớp. Một preload bao gồm lớp đầu tiên, giống hệt như getFlow thực hiện:
| Lớp | Được tải bởi | Được làm ấm bởi preload |
|---|---|---|
| Flow JSON — biến thể được chọn, ID sản phẩm của nó, và Remote Config | getFlow | Có |
| Bố cục giao diện — cấu trúc, kiểu dáng và văn bản của màn hình | createFlowView | Không |
| Hình ảnh, bao gồm khung tĩnh thay thế cho phần tử video | createFlowView, chạy nền | Không |
| Tệp video | Trình phát hệ thống, khi màn hình hiển thị | Không được SDK lưu cache |
Vậy lần gọi createFlowView đầu tiên cho một layout nhất định vẫn tốn một lần round trip sau khi preload. Sau đó SDK sẽ lưu layout đó vào disk cache, cache này tồn tại qua cả lần khởi động lại ứng dụng, nên chi phí chỉ rơi vào lần request đầu tiên chứ không phải mỗi lần.
Bỏ qua phân khúc đối tượng
Để làm nóng cache mà không cần chờ phân khúc đối tượng, hãy dùng biến thể default-audience. Biến thể này không cần timeout:
await adapty.preloadFlowsForDefaultAudience(['main_paywall']);
Hiển thị media màn hình đầu tiên từ app bundle
Một flow tải hình ảnh và video từ Adapty. Để hiển thị media của màn hình đầu tiên ngay lập tức, hãy phục vụ nó từ app bundle thay thế. Đây là cách tốt để tái sử dụng media bạn đã có sẵn, chẳng hạn như hình ảnh của một onboarding gốc hiện có.
- Trong Flow & Paywall Builder, đặt custom media ID cho hình ảnh hoặc video. File bạn tải lên đó sẽ là fallback.
- Thêm file vào các dự án native: bundle ứng dụng iOS và thư mục
assetscủa Android. - Khi tạo flow view, truyền file đã đóng gói cho ID đó trong
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 });
Các file đóng gói sẽ tăng kích thước tải xuống của app, vì vậy chỉ nên đóng gói những media người dùng nhìn thấy đầu tiên.
Những media bạn không đóng gói vẫn hiển thị ngay lập tức: layout của flow chứa sẵn một bản sao độ phân giải thấp của từng ảnh, bao gồm cả khung tĩnh của video, và hiển thị bản đó cho đến khi file đầy đủ tải xong.
Để xem toàn bộ tài liệu tham khảo về customAssets, xem Tùy chỉnh assets.
Tối ưu cho kết nối kém
Đối với các thị trường có kết nối kém liên tục (khu vực nông thôn, phương tiện giao thông, vùng bị ảnh hưởng bởi định tuyến mạng):
- Đặt
fetchPolicy: 'return_cache_data_else_load'cho mọi lần fetch ngoại trừ lần đầu tiên. - Cấu hình paywall dự phòng cho mọi placement trong Adapty Dashboard.
- Đặt
loadTimeoutMstừ 3–5 giây và chấp nhận paywall dự phòng khi hết thời gian chờ. - Không chặn việc hiển thị flow vào kết quả của
getProfile(). GọigetFlowđộc lập để tránh trường hợp profile chậm làm chặn giao diện.