Warm Start : essence, démarrage à chaud et optimisation dans Android

Auteur : IT Sectr Publié le : 2026-03-31 Temps de lecture : 8 min

Warm Start est un scénario de démarrage d'application Android où le processus de l'application existe déjà en mémoire (par exemple, après avoir été minimisé), mais l'Activity a été détruite par le système pour économiser les ressources. Application.onCreate a déjà été exécuté, les classes sont chargées, mais l'UI est recréée. Selon Google, 2024, Warm Start prend 200 à 800 ms et représente environ 40 % de tous les démarrages sur les appareils avec 4 Go de RAM.

Points clés

  • Warm Start — démarrage d'une application avec un processus existant, mais sans Activity en mémoire
  • Différence de Cold Start : Application.onCreate n'est pas exécuté, les classes sont déjà chargées
  • Temps Warm Start prend 200–800 ms contre 1–5 secondes pour Cold Start
  • Scénarios : retour à l'application après plusieurs heures, suppression de l'Activity par OOM-killer
  • Optimisation se concentre sur la préservation de l'état de l'Activity et la mise en cache des données

Qu'est-ce que Warm Start

Warm Start est un état entre Cold Start et Hot Start : le processus de l'application existe en mémoire (parfois dans le cache d'arrière-plan Linux), mais l'Activity n'est pas active et sera recréée. Lorsque Android manque de RAM, il peut supprimer l'Activity de la pile, laissant le processus vivant. Lorsque l'utilisateur revient à l'application, un Warm Start se produit : une nouvelle instance d'Activity est créée, les méthodes de cycle de vie onCreate → onStart → onResume sont exécutées, mais Application.onCreate et le chargement des classes sont ignorés.

Causes de Warm Start

Android décide de supprimer l'Activity en fonction de la priorité du processus (rang d'importance). Une Activity en arrière-plan (niveau PROCESS_STATE_IMPORTANT_FOREGROUND ou PROCESS_STATE_TOP_SLEEPING) peut être détruite 5 à 30 minutes après la minimisation de l'application, selon la RAM disponible. Sur les appareils avec 3 Go de RAM, l'Activity peut être supprimée en 10 minutes ; sur les appareils avec 8 Go de RAM, après plusieurs heures. Important : pendant Warm Start, onSaveInstanceState est appelé avant la destruction de l'Activity, et le développeur peut sauvegarder l'état de l'UI.

Perception de l'utilisateur

L'utilisateur ne voit pas la différence entre Warm et Cold Start — il appuie simplement sur l'icône de l'application et attend. Cependant, pendant Warm Start, un écran blanc peut apparaître si l'application n'a pas défini de thème personnalisé pour la fenêtre de démarrage. Google recommande de définir un thème personnalisé dans le manifeste (Theme.AppCompat.Light ou Theme.Material3.DayNight) pour l'Activity de démarrage, afin d'éviter le scintillement de l'écran blanc/noir pendant Warm Start. Sur Android 12+, l'API SplashScreen masque également cet effet.

Warm Start vs Cold Start vs Hot Start

Comprendre la différence entre les trois types de démarrage est essentiel pour choisir la bonne stratégie de profilage et d'optimisation. Chaque type a sa propre durée, ses propres goulots d'étranglement et ses propres outils de mesure.

CritèreCold StartWarm StartHot Start
ProcessusCréé à partir de zéroExiste en mémoireExiste en mémoire
Application.onCreateExécutéNon exécutéNon exécuté
ActivityCréée à partir de zéroCréée à partir de zéroRestaurée depuis la pile
Temps1–5 secondes200–800 ms< 200 ms
Activity.onCreateCompletComplet (avec restauration)Ignoré

En pratique, Warm Start représente 30 % à 60 % de tous les démarrages d'applications, selon les habitudes de l'utilisateur et la RAM de l'appareil. Les utilisateurs qui gardent de nombreuses applications ouvertes (multitâche) rencontrent Warm Start plus souvent. Pour les réseaux sociaux et les messageries, Warm Start est le scénario le plus courant car l'application est toujours en arrière-plan. Pour les applications bancaires, au contraire, Cold Start prédomine (nettoyage forcé du processus pour des raisons de sécurité).

Phases du démarrage à chaud

Warm Start se compose de trois phases, chacune pouvant être mesurée et optimisée. Contrairement à Cold Start, il n'y a pas de phase de fork ni de chargement de classes, mais il y a une phase de restauration d'état qui peut être coûteuse.

Phase 1 : Fenêtre de démarrage (fond de fenêtre)

Le système vérifie si l'application a un thème pour la fenêtre de démarrage. Si le thème n'est pas défini, un écran blanc (ou noir, selon le système) s'affiche. Si le thème est défini, le fond du thème est affiché. Cette phase prend 10–30 ms, mais elle est visuellement perceptible si le thème ne correspond pas à l'UI réelle de l'application. Utilisez Theme.Material3.DayNight avec un windowBackground personnalisé dont la couleur correspond au fond du premier écran — cela crée un effet de chargement instantané.

Phase 2 : Création de l'Activity (restauration)

Le système appelle onCreate en passant le Bundle savedInstanceState qui a été sauvegardé dans onSaveInstanceState avant la destruction de l'Activity. Si l'application a correctement sauvegardé l'état (texte des champs, position de défilement, données ViewModel), la restauration se produit rapidement. Sinon, l'Activity commence à partir de zéro et l'utilisateur voit un chargeur pendant le chargement des données. Point clé : les objets ViewModel survivent à Warm Start seulement si le processus n'a pas été détruit — pendant Warm Start, le ViewModel reste en mémoire.

Phase 3 : Première image (TTFD)

Après onCreate, onStart → onResume sont exécutés, et le système déclenche le premier dessin. TTFD (Time To First Draw) pour Warm Start doit être inférieur à 300 ms sur un appareil de milieu de gamme. Si le premier écran contient un RecyclerView complexe avec des Views lourdes ou charge des images depuis le réseau, TTFD peut dépasser le seuil. Utilisez Placeholder et Shimmer pour un chargement fluide du contenu après la première image.

Comment mesurer Warm Start

Mesurer Warm Start est plus complexe que Cold Start car vous devez simuler l'état où le processus est vivant mais l'Activity est détruite. La commande ADB standard avec le drapeau -S ne fonctionne pas — elle tue le processus. Utilisez des approches différentes pour Warm Start.

ADB shell am start sans -S

D'abord, lancez l'application via adb shell monkey ou appuyez sur l'icône, puis minimisez-la (adb shell input keyevent 3 keyevent HOME). Attendez 5 à 10 secondes pour que le système puisse supprimer l'Activity, puis exécutez adb shell am start -W (sans -S). La commande retournera un temps de démarrage plus court que Cold Start. Pour la reproductibilité, utilisez un script : lancer → attendre → accueil → attendre → lancer.

bash
# Simulation de Warm Start via ADB
$ adb shell am start -W \
    com.example.app/.MainActivity

# Sortie (Warm Start) :
# ThisTime: 412 ms
# TotalTime: 412 ms
# WaitTime: 423 ms

Macrobenchmark pour Warm Start

La bibliothèque androidx.benchmark.macro prend en charge la mesure de Warm Start. Dans le test, définissez startupMode = StartupMode.WARM — la bibliothèque lancera l'application, la minimisera, attendra (délai configurable), puis mesurera le redémarrage. Macrobenchmark effectue 10 à 20 itérations et calcule les percentiles. Dans CI/CD, vous pouvez définir un seuil : si P50 Warm Start dépasse 600 ms, le test échoue. Cela permet de suivre les régressions à chaque commit.

Firebase Performance Monitoring

Firebase distingue automatiquement Cold et Warm Start en fonction du temps depuis la dernière fermeture de l'application. Si l'application a été ouverte dans les 30 dernières minutes, Firebase classe le démarrage comme Warm. Dans la console Firebase, vous verrez des graphiques séparés pour chaque type de démarrage, vous permettant d'évaluer l'efficacité des optimisations. Par exemple, après avoir implémenté la préservation d'état dans ViewModel, vous pouvez voir une réduction de 30 % du temps de Warm Start.

Comment optimiser Warm Start

L'optimisation de Warm Start se concentre sur deux domaines : accélérer Activity.onCreate et la restauration correcte de l'état. Puisque Application.onCreate et le chargement des classes sont déjà terminés, le principal goulot d'étranglement est le code UI du premier écran.

Restauration asynchrone de l'état

Si l'état sauvegardé (savedInstanceState) contient des données nécessitant une désérialisation (Bitmap, String, JSON), faites-le sur un thread d'arrière-plan. Au lieu de lire directement depuis Bundle dans onCreate, lancez une coroutine et affichez un écran shimmer. En pratique, la désérialisation de Bundle sur un appareil de milieu de gamme prend 20–100 ms — cela semble peu, mais pour Warm Start, c'est 10–50 % du temps total. Utilisez le Saved State Module de Jetpack, qui sauvegarde et restaure automatiquement l'état du ViewModel dans le Bundle ou la base de données.

Optimisation de setContentView

L'inflation du layout XML est l'une des étapes les plus coûteuses de Warm Start. Si le premier écran utilise un CoordinatorLayout complexe avec AppBar, CollapsingToolbar, NestedScrollView plus trois RecyclerViews, le temps d'inflation peut atteindre 300 ms. Solutions : utilisez ConstraintLayout pour une hiérarchie plate, appliquez ViewStub pour les sections non visibles au démarrage (bottom sheet, dialog), activez l'inflation asynchrone pour les fragments lourds via AsyncLayoutInflater. Dans Jetpack Compose, l'inflation n'est pas nécessaire, mais la compilation de l'arbre Compose pendant Warm Start peut prendre un temps similaire.

Mise en cache des données

Pendant Warm Start, les données que l'application a chargées dans la session précédente peuvent déjà être dans le cache : base de données Room, SharedPreferences, cache en mémoire dans ViewModel. Si votre premier écran affiche une liste du serveur, vérifiez le cache au démarrage et mettez à jour les données en arrière-plan. Utilisez la stratégie cache-then-network : d'abord afficher les données en cache (instantanément), puis mettre à jour depuis le serveur (asynchrone). Cela réduit le temps perçu de Warm Start à 100–200 ms.

kotlin
// ViewModel avec mise en cache pour Warm Start
class FeedViewModel : ViewModel() {
    private val cache = MutableStateFlow<List<Item>>(emptyList())

    init {
        // Cache d'abord, puis réseau
        viewModelScope.launch {
            cache.emit(db.getItems()) // Warm Start : données déjà en BD
            cache.emit(api.fetchItems()) // Mise à jour en arrière-plan
        }
    }
}

Préservation de l'état pendant Warm Start

La préservation correcte de l'état est le facteur clé qui distingue un bon Warm Start d'un mauvais. L'utilisateur s'attend à revenir à l'application et à voir exactement ce qu'il a laissé — y compris la position de défilement, le texte dans les champs et les onglets sélectionnés.

onSaveInstanceState

Le système appelle onSaveInstanceState lorsque l'Activity est détruite, mais AVANT que le processus ne soit tué. Seuls les types de données simples (String, Int, Parcelable, Serializable) sont sauvegardés dans le Bundle. Pour les données complexes, utilisez SavedStateHandle dans ViewModel — il sauvegarde et restaure automatiquement les champs pendant Warm Start. Contrairement à onSaveInstanceState, SavedStateHandle fonctionne même si le processus survit à Warm Start (ViewModel n'est pas détruit). Exemple : pour le texte dans EditText, utilisez SavedStateHandle.getLiveData(«text») — le texte sera automatiquement sauvegardé et restauré.

ViewModel et Warm Start

Si le processus n'a pas été tué pendant Warm Start, le ViewModel reste en mémoire et onCleared n'est pas appelé. Cela signifie que toutes les données chargées dans la session précédente sont instantanément disponibles. Cependant, si le processus a été tué (appareil en veille prolongée pendant plus de 30 minutes), le ViewModel est détruit et recréé avec SavedStateHandle. Pour un comportement correct du ViewModel pendant Warm Start, utilisez SavedStateHandle avec les champs qui doivent être restaurés dans tout scénario. Différence : ViewModel avec @HiltViewModel prend en charge SavedStateHandle automatiquement.

MécanismeProcessus vivantProcessus tué
ViewModelDonnées en mémoireDétruit, recréé
SavedStateHandleDonnées en mémoireRestauré depuis Bundle
onSaveInstanceStateAppelé lors de la suppression de l'ActivityNon appelé
Room DBCache disponibleCache disponible (disque)

Sauvegarde de la position de défilement RecyclerView

L'un des problèmes les plus courants de Warm Start — perdre la position de défilement. L'utilisateur a défilé jusqu'au 50e élément, a minimisé l'application, est revenu — et voit le début de la liste. Solution : sauvegardez layoutManager.onSaveInstanceState (sauvegarde la position et le décalage du premier élément visible) et restaurez-le dans onRestoreInstanceState. Vous pouvez également sauvegarder la dernière position visible dans SharedPreferences avec une clé de date/heure pour restaurer rapidement la position pendant Warm Start.

kotlin
// Sauvegarder la position de défilement RecyclerView
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable(
        "rv_state", binding.recyclerView
            .layoutManager?.onSaveInstanceState()
    )
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    savedInstanceState?.getParcelable<Parcelable>("rv_state")
        ?.let { binding.recyclerView.layoutManager?.onRestoreInstanceState(it) }
}

Exemples de code pour Warm Start

Deux exemples pratiques d'optimisation de Warm Start : utilisation de SavedStateHandle dans ViewModel et restauration asynchrone de données complexes après le démarrage.

ViewModel avec SavedStateHandle

SavedStateHandle sauvegarde automatiquement les champs dans le Bundle et les restaure pendant Warm Start. Le champ de profil utilisateur (String, JSON) sera restauré sans requêtes inutiles au serveur. Si le processus a été tué, SavedStateHandle charge le dernier état sauvegardé depuis le Bundle.

kotlin
class ProfileViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val profile: StateFlow<Profile?>
        get() = savedStateHandle
            .getStateFlow("profile", null)

    fun loadProfile(id: String) {
        viewModelScope.launch {
            savedStateHandle["profile"] =
                api.getProfile(id)
        }
    }
}

// Warm Start : profile n'est pas null, UI sans chargeur
// Après chargement : profile se met à jour dans SavedStateHandle

AsyncLayoutInflater pour les écrans lourds

Si le premier écran contient un layout complexe (carte, dégradé, plusieurs listes), utilisez AsyncLayoutInflater pour gonfler les éléments lourds en arrière-plan. Pendant le gonflage du layout, affichez un placeholder avec effet shimmer. Ceci est particulièrement important pour Warm Start, où chaque milliseconde compte. AsyncLayoutInflater s'exécute sur un thread d'arrière-plan et passe le View prêt à un callback sur le thread principal.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Layout placeholder pour rendu instantané
        setContentView(R.layout.placeholder_shimmer)

        // Chargement asynchrone du layout lourd
        AsyncLayoutInflater(this).inflate(
            R.layout.activity_main_complex,
            findViewById(R.id.container)
        ) { view, resId, parent ->
            parent?.removeAllViews()
            parent?.addView(view)
        }
    }
}

Foire aux questions

Warm Start peut-il se transformer en Cold Start ?

Oui, si au moment de Warm Start le système décide de tuer le processus de l'application (par exemple, pour libérer de la mémoire pour une autre application), le démarrage devient Cold Start à partir de zéro. Cela se produit sur les appareils avec 2–3 Go de RAM lorsque plusieurs applications fonctionnent simultanément. En fait, Warm Start n'est garanti que pendant 10–20 minutes après la minimisation sur les appareils de milieu de gamme.

Le ViewModel est-il préservé pendant Warm Start ?

Oui, si le processus n'a pas été tué, le ViewModel reste en mémoire et onCleared n'est pas appelé. C'est un avantage clé de Warm Start : toutes les données chargées via des requêtes réseau, le cache dans ViewModel — tout est disponible instantanément. Si le processus a été tué, le ViewModel est recréé via ViewModelProvider.Factory ou @HiltViewModel, et SavedStateHandle restaure les champs sauvegardés.

Pourquoi Warm Start peut-il être plus lent que Cold Start ?

Théoriquement, Warm Start est toujours plus rapide que Cold Start, mais en pratique il existe des scénarios où la différence est minime : si Application.onCreate était léger (50 ms) et Activity.onCreate est lourd (800 ms), alors Warm Start (800 ms) est presque égal à Cold Start (850 ms). Dans ce cas, vous devez optimiser non pas Application, mais Activity.onCreate — il devient le goulot d'étranglement pour Warm Start.

Comment l'API SplashScreen affecte-t-elle Warm Start ?

L'API SplashScreen sur Android 12+ affiche un splash système (icône sur fond coloré) immédiatement au démarrage — à la fois pour Cold et Warm Start. Pour Warm Start, le splash est affiché seulement 100–300 ms, après quoi il est remplacé par l'UI de l'application. SplashScreen n'accélère pas le démarrage lui-même, mais masque le temps de création de l'Activity, améliorant la perception.

Est-il nécessaire d'optimiser Warm Start si Cold Start est déjà rapide ?

Oui, car Warm Start se produit 2 à 3 fois plus souvent que Cold Start. Si Cold Start prend 1,2 seconde et Warm Start prend 600 ms, alors 40 % des démarrages (Warm) prennent encore 0,6 seconde, ce qui est perceptible. Optimiser Warm Start à 200–300 ms donne à l'utilisateur une sensation de retour instantané. Sur les appareils avec 6+ Go de RAM, Warm Start peut représenter jusqu'à 80 % de tous les démarrages, faisant de son optimisation une priorité.

Résumé

  • Warm Start — démarrage d'application avec processus existant, sans Activity en mémoire, temps 200–800 ms
  • Principale différence de Cold Start : Application.onCreate n'est pas exécuté, classes chargées
  • Trois phases de Warm Start : fenêtre de démarrage → création de l'Activity → première image
  • Mesuré via ADB sans le drapeau -S ou Macrobenchmark avec StartupMode.WARM
  • Optimisation : SavedStateHandle, AsyncLayoutInflater, cache-then-network, ConstraintLayout
  • ViewModel est préservé pendant Warm Start (processus vivant) — données instantanément disponibles
  • Warm Start représente 40–80 % de tous les démarrages d'applications

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi