Introduction
La planification de capacité pour React Native (React Native capacity planning) consiste à prévoir et à fournir le débit côté client, backend et paiement dont votre app a besoin, sans faire exploser les ressources de l'appareil ni les coûts serveurs. À la clé : moins de crashs et d'ANR, une UX fluide aux heures de pointe, et une montée en charge maîtrisée pour vos API et vos parcours de paiement.
Ce guide propose un workflow clair, des formules de dimensionnement et des exemples concrets couvrant Expo, Android, REST API, Google Play Billing et Stripe. Il se termine par un pilote local sûr à exécuter pour dérisquer la croissance. Les mots-clés utiles à conserver dans votre stratégie incluent React Native scaling, React Native resources, React Native limits et React Native sizing.
Vue d'ensemble du workflow
Appliquez ce flux simple et répétable à chaque grande fonctionnalité et à chaque release :
- Définir les workloads et les objectifs
- Cibles et tiers d'appareils : Android bas, moyen, haut; iOS récent si pertinent.
- Forme de charge : DAU/WAU, sessions par utilisateur, écrans par session, requêtes par écran, tailles d'upload/download, taux d'achat.
- Objectifs : démarrage p75/p95, time to interactive (TTI), fluidité du scroll, latence API p95, temps de complétion d'achat.
- Établir le baseline de l'app
- Activez le moteur JS de production (par ex. Hermes) en build release.
- Mesurez : cold start, TTI, temps de frame JS et UI, mémoire RSS et heap JS, réseau par écran.
- Relevez les chiffres sur au moins 3 appareils (bas, moyen, haut).
- Modéliser le pic et la concurrence
- Calculez les utilisateurs actifs au pic et la concurrence de requêtes par écran.
- Convertissez les actions en QPS API, bande passante images, et événements de paiement/webhook.
- Fixer des budgets
- Client : travail JS par frame, travail UI par frame, mémoire par écran, réseau par écran.
- Serveur : RPS par endpoint, budgets de latence p95, débit des API d'achat, capacité des workers webhook.
- Mettre en place des contrôles
- Pagination, batching de requêtes, limites de concurrence, caching et debouncing.
- Backoff, timeouts et annulation pour les appels réseau.
- Idempotence et files bornées pour paiements et webhooks.
- Tester sous stress
- Simulez réseaux lents, perte de paquets, listes volumineuses et rafales d'actions.
- Lancez des tests de charge API avec un mix de trafic réaliste.
- Surveiller et itérer
- Suivez les signaux listés ci-dessous. Ajustez budgets et contrôles avant chaque événement de croissance (campagnes, lancements, fêtes).
Modèle de dimensionnement et entrées
Traduisez le comportement en chiffres exploitables. Commencez grossier, puis affinez.
Budgets de temps côté client
- 60 fps visés donnent 16,7 ms par frame.
- Budget travail du thread JS: typiquement sous 4-6 ms, pointes sous 10 ms.
- Budget travail du thread UI: typiquement sous 8-10 ms.
- Différez le non-urgent vers l'inactivité avec InteractionManager ou échelonnez sur plusieurs frames.
Budgets mémoire (focus Android)
- Maintenez le RSS en régime stabilisé bien en-deçà des limites. Règle pratique: 200-300 Mo sur appareils milieu de gamme, sensiblement moins en entrée de gamme.
- Évitez de gros bitmaps décodés en mémoire. Redimensionnez côté serveur ou, a minima, adaptez aux dimensions à l'écran.
- Utilisez FlatList/SectionList avec virtualisation et removeClippedSubviews pour limiter le nombre de vues en vie.
Budgets réseau
- Exemple d'écran liste: 20 items, chacun avec une image de 100 Ko après cache et resize.
- Budget par page: ~2 Mo + JSON (disons 50-150 Ko).
- Limitez les fetchs concurrents (par ex. 4) pour protéger les threads JS/UI et les radios.
- Préchargez la page suivante lorsque l'utilisateur dépasse 70 % de scroll.
Débit API
- Formule de pic:
QPS_peak = concurrent_users_peak * req_par_utilisateur_par_minute / 60. - Exemple: 5 000 utilisateurs concurrents générant 12 req/min => 1 000 QPS. Avec 50 % de marge, visez 1 500 QPS de capacité.
Débit d'achat et de facturation
- Supposez 2-3 événements webhook par achat (création, confirmation, validation de reçu). Si vous attendez 30 achats/min au pic, prévoyez au moins 90 événements/min pour les workers, avec 2x de marge pour les bursts.
- Cadrez la latence bout-en-bout de l'achat (p95 < 5 s du tap à l'écran de confirmation) et alignez timeouts client/serveur.
Stockage et files offline
- Bornes pour les files d'événements offline (par ex. 100-500 items) avec backpressure et politiques de drop pour les événements non critiques.
Signaux, limites et marges de sécurité
Signaux clés côté client
- Frames perdues JS et UI, frames longues pendant scroll/gestes.
- Temps de démarrage et TTI.
- Croissance mémoire RSS et heap JS; pression GC.
- Taux d'ANR (Android) et utilisateurs sans crash.
Signaux réseau et serveur
- Latence p95/p99 et taux d'erreur par endpoint.
- Retries, timeouts et ouvertures de disjoncteur (circuit breaker).
- Profondeur de file webhook, latence de traitement et dead-letter.
Limites à respecter
- Rendu: budget de 16,7 ms/frame; évitez layouts coûteux et ponts synchrones.
- Mémoire: soyez conservateur en Android entrée de gamme (killers agressifs).
- Bridge: évitez d'envoyer de gros blobs JSON par frame; batcher et compresser.
Marges de sécurité
- Conservez 30-50 % de headroom pour CPU, mémoire et débit serveur autour des pics attendus.
- Appliquez rate limiters et backpressure côté client et serveur.
- Concevez une dégradation gracieuse: skeleton UIs, pages plus petites, travail non critique différé.
Exemples pratiques
1) Expo + REST API : écran liste avec images
Objectif: scroll fluide à 60 fps sur une liste produit pendant le fetch d'images et de JSON.
Budgets côté client
- JS par frame < 6 ms.
- UI par frame < 10 ms.
- Réseau par page ~2 Mo.
Paramètres FlatList
<FlatList
data={items}
keyExtractor={(it) => it.id}
renderItem={renderItem}
initialNumToRender={10}
maxToRenderPerBatch={10}
windowSize={5}
removeClippedSubviews
onEndReachedThreshold={0.7}
onEndReached={loadNextPage}
/>
Préchargement d'images avec petite file contrainte
const queue: Array<() => void> = [];
let active = 0;
const LIMIT = 4;
function runNext() {
if (active >= LIMIT) return;
const task = queue.shift();
if (!task) return;
active++;
task();
}
function limitedFetch(url: string): Promise<Response> {
return new Promise((resolve, reject) => {
const task = () => {
fetch(url)
.then(resolve)
.catch(reject)
.finally(() => { active--; runNext(); });
};
queue.push(task);
runNext();
});
}
async function prefetchImage(uri: string) {
await limitedFetch(uri);
}
Mesurer localement
console.time('list-first-render');
// après la première peinture significative
console.timeEnd('list-first-render');
Si le scroll saccade, réduisez le nombre de fetchs concurrents à 2, diminuez la taille des images, ou différez le rendu des items non visibles.
2) Budget performance Android pour éviter ANR et OOM
- Maintenez peu de vues vivantes via la virtualisation. Évitez les FlatList imbriquées; préférez SectionList.
- Évitez les parsings JSON synchrones volumineux sur le thread JS. Si les payloads sont gros, paginez côté serveur ou découpez le travail avec setImmediate et InteractionManager.
- Downsamplez les images à la taille d'affichage. Libérez les ressources image quand les lignes sortent de l'écran.
- Surveillez la mémoire sur appareils d'entrée de gamme; testez des sessions longues (20-30 minutes) pour révéler les fuites.
3) Google Play Billing et Stripe : gestion d'un pic
Scénario: une promo de 20 minutes déclenche un pic x10 des achats.
Client
- Utilisez des clés d'idempotence pour les appels de confirmation d'achat.
- Impos ez des timeouts réseau (par ex. 5-10 s) et des retries avec backoff exponentiel.
- Affichez des reçus tolérants à l'offline et relancez en arrière-plan si nécessaire.
Serveur
- Cible de débit: si le baseline est 30 achats/min, planifiez 300/min pendant la promo. Avec 2x de marge, dimensionnez pour 600/min.
- Webhooks: supposez 2-3 événements par achat. Dimensionnez les workers pour 1 200-1 800 événements/minute.
- Gardez des handlers webhook idempotents et rapides; déportez le lourd dans une file interne.
Esquisse de concurrence de worker webhook
type Job = { id: string; payload: any };
const inflight = new Set<string>();
const CONCURRENCY = 16; // ajuster selon CPU et I/O
async function handle(job: Job) {
if (inflight.has(job.id)) return; // garde d'idempotence
inflight.add(job.id);
try {
// valider la signature, mettre à jour l'état, enqueuer le suivi
} finally {
inflight.delete(job.id);
}
}
Surveillez la profondeur de file et la latence de traitement; autoscalez les workers avant la fenêtre promo.
Plan pilote local
Objectif: prouver qu'un écran critique et un flux d'achat respectent les budgets sur appareils Android bas/milieu/haut, et que votre API et vos workers webhook encaissent un mini-pic réaliste.
Périmètre (étroit, mesurable)
- Écran: liste produit avec images et pagination.
- Parcours: un achat consommable de bout en bout.
Étapes
- Définissez les cibles: scroll avec < 5 % de frames longues, TTI < 2,5 s en milieu de gamme, p95 API < 300 ms, p95 achat < 5 s.
- Appliquez les réglages FlatList et une file de fetch avec LIMIT=4.
- Redimensionnez les images à la taille d'affichage et activez le cache HTTP.
- Ajoutez des timeouts et du backoff aux appels réseau; imposez des clés d'idempotence sur les appels d'achat.
- Créez un petit worker webhook à concurrence bornée et journalisation.
- Simulez des réseaux lents (3G/4G lent) et 2 % de perte; vérifiez scroll et achat.
- Lancez une charge locale à 2x la charge pilote attendue sur l'API d'achat; confirmez latence et erreurs.
- Documentez budgets et résultats. Si échec, ajustez concurrence, tailles de lot et images, puis rejouez.
Ce pilote est étroit, mesurable et simple à inspecter localement avant un déploiement plus large.
Conclusion
La planification de capacité en React Native commence sur l'appareil: protégez le temps de frame, la mémoire et la batterie avec des budgets et des contrôles explicites. Reliez les actions client au débit serveur, et dimensionnez vos endpoints REST et webhooks de billing avec une marge réaliste.
Adoptez le workflow, exécutez le pilote local, et verrouillez budgets et signaux. Revalidez vos hypothèses avant les lancements et promotions, et augmentez la capacité en amont des pics planifiés. Avec des exemples concrets et un petit pilote vérifié, vous livrez en confiance et évitez les mauvaises surprises.