Aller au contenu
useffect.sh
Planifier 30 min avec un senior
Performance

Cold start (temps de démarrage)

Le lancement de l’app depuis zéro, processus compris : natif, chargement du bundle, premier rendu React, jusqu’à l’écran utilisable (TTI).

Définition

Le cold start, ou démarrage à froid, est le lancement d’une app quand son processus n’existe pas encore : premier lancement depuis le redémarrage du téléphone, ou relance après que le système a tué l’app. Android distingue le cold start du warm start (processus vivant, Activity à recréer) et du hot start (tout est encore en mémoire), et mesure deux étapes : le Time To Initial Display (TTID), première frame affichée, et le Time To Full Display (TTFD), écran réellement utilisable, que l’app signale avec reportFullyDrawn. Pour une app React Native, le cold start empile le démarrage natif (dyld et initialisation sur iOS, Application sur Android), la création du runtime Hermes, le chargement et l’exécution du bundle, puis le premier rendu React et les premières requêtes. Ce que les équipes appellent TTI (time to interactive) correspond au TTFD. Android vitals le mesure dans la Play Console et signale les démarrages à froid trop lents.

Dans une vraie app

La mesure vient avant toute optimisation, en build release uniquement. Sur Android, adb shell am start -W et la ligne Displayed de logcat donnent le TTID ; reportFullyDrawn (appelable depuis un module natif au moment où l’écran est prêt) donne le TTFD. Sur iOS, le template App Launch d’Instruments découpe le pre-main (chargement des frameworks dynamiques, initialiseurs statiques) et le post-main. Côté JavaScript, performance.mark et le panneau Performance de React Native DevTools montrent le temps entre l’exécution du bundle et le premier commit React. Un vrai device d’entrée de gamme Android est la référence, pas le simulateur.

Les causes habituelles, dans l’ordre où je les trouve : du travail au niveau module (initialisation de SDK, lecture de stockage, gros require d’images) exécuté avant le premier rendu ; un bundle qui charge tous les écrans alors que require inline ou le lazy loading des routes permet de différer ; une cascade de requêtes réseau bloquantes derrière le splash ; des polyfills Intl lourds ; et sur iOS un use_frameworks! dynamique qui multiplie les frameworks à charger au pre-main. Hermes et son bytecode règlent la partie parsing, pas ces cinq points.

Ce que je regarde en premier dans un projet : ce qui s’exécute entre index.js et le premier écran, le nombre de providers imbriqués à la racine, et si le splash est masqué sur un événement précis (données prêtes) plutôt qu’un timer.

Nos offres sur ce sujet

Sources

Les 35 termes du glossaire

Un de ces sujets bloque votre app ?

30 minutes avec un senior pour regarder le problème dans votre code. Gratuit.