Temps de démarrage de l'application

Les utilisateurs s'attendent à ce que les applications se chargent rapidement et soient réactives. Une application dont le démarrage est lent ne répond pas à cette attente et peut décevoir les utilisateurs. Cette mauvaise expérience peut conduire l'utilisateur à donner une mauvaise note à votre application sur le Play Store, voire à l'abandonner complètement.

Cette page fournit des informations pour vous aider à optimiser le délai de démarrage de votre application. Elle offre un aperçu des mécanismes internes du processus de lancement, explique comment profiler les performances de démarrage et présente certains problèmes courants de démarrage, ainsi que des conseils pour y remédier.

Comprendre les différents états de démarrage de l'application

Le lancement d'une application peut avoir l'un des trois états suivants : démarrage à froid, démarrage tiède ou démarrage à chaud. Chaque état a une incidence sur le délai nécessaire pour que votre application soit visible par l'utilisateur. À froid, votre application part de zéro. Dans les autres états, le système doit faire passer l'application en cours d'exécution de l'arrière-plan au premier plan.

Nous vous recommandons de toujours optimiser votre application comme si elle démarrait d'office à froid. Cela peut également améliorer les performances des démarrages tiède et à chaud.

Pour optimiser votre application afin qu'elle démarre rapidement, il est utile de comprendre ce qui se passe au niveau du système et de l'application, ainsi que la façon dont ils interagissent, dans chacun de ces états.

Le délai d'affichage initial (TTID) et le délai d'affichage total (TTFD) sont deux métriques importantes pour déterminer le démarrage de l'application. Le TTID correspond au temps nécessaire pour afficher le premier frame et le TTFD correspond au délai nécessaire pour que l'application devienne entièrement interactive. Les deux sont tout aussi importants, car le TTID indique à l'utilisateur que l'application est en cours de chargement, et le TTFD indique à quel moment l'application est réellement utilisable. Si l'un de ces délais est trop long, l'utilisateur peut quitter l'application avant même qu'elle ne soit complètement chargée.

Démarrage à froid

Le terme "démarrage à froid" désigne le démarrage d'une application à partir de zéro. Cela signifie que jusqu'au démarrage, le processus du système crée le processus de l'application. Les démarrages à froid se produisent dans les cas où votre application se lance pour la première fois depuis le démarrage de l'appareil ou lorsque le système a arrêté l'application.

Ce type de démarrage représente le plus grand défi pour réduire le délai de démarrage, car le système et l'application ont alors davantage de travail par rapport aux autres états de lancement.

Au début d'un démarrage à froid, le système doit effectuer les trois tâches suivantes :

  1. Charger et lancer l'application.
  2. Afficher une fenêtre de démarrage vide pour l'application immédiatement après le lancement.
  3. Créer le processus d'application.

Dès que le système a créé le processus d'application, ce processus est responsable des étapes suivantes :

  1. Créer l'objet d'application.
  2. Lancer le thread principal.
  3. Créer l'activité principale.
  4. Initialisez l'UI.
  5. Dessinez l'UI à l'écran.

Une fois la première visualisation terminée, le processus système remplace la fenêtre d'arrière-plan affichée par l'activité principale. L'utilisateur peut alors commencer à utiliser l'application.

Pour en savoir plus sur les phases de mise en page dans Compose, consultez Phases de Jetpack Compose.

Des problèmes de performances peuvent survenir au moment où l'application et l'activité hôte sont créées.

Création d'applications

Lorsque l'application est lancée, la fenêtre de démarrage vide reste affichée jusqu'à ce que le système ait fini d'afficher l'application. À ce stade, le processus système remplace la fenêtre de démarrage de votre application, ce qui permet à l'utilisateur d'interagir avec elle.

Si vous remplacez Application.onCreate dans votre propre application, le système appelle la méthode onCreate sur votre objet d'application. Par la suite, l'application génère le thread principal, également appelé thread UI, et le charge de créer l'activité hôte de votre application.

À ce stade, les processus au niveau du système et de l'application se déroulent conformément aux étapes du cycle de vie de l'application.

Création de l'activité

Une fois que le processus de l'application a créé votre activité, celle-ci effectue les opérations suivantes :

  1. Initialisation des valeurs
  2. Appel des constructeurs
  3. Appel à la méthode de rappel, telle que Activity.onCreate, adaptée à l'état du cycle de vie actuel de l'activité

En général, la méthode onCreate a l'impact le plus élevé sur le temps de chargement. Dans une application Jetpack Compose, la surcharge de la méthode onCreate provient souvent de la composition initiale. Cela se produit lorsque votre application appelle setContent et invoque vos composables de premier niveau. Une hiérarchie d'UI profonde ou complexe, ou des composables qui effectuent des calculs lourds sur le thread principal, peuvent augmenter ce temps de composition.

Démarrage tiède

Un démarrage tiède englobe un sous-ensemble des opérations qui ont lieu lors d'un démarrage à froid. Pour autant, ce sous-ensemble représente une surcharge plus importante que celle d'un démarrage à chaud. De nombreux états potentiels peuvent être considérés comme des démarrages tièdes, par exemple :

  • L'utilisateur quitte votre application, puis la relance. Le processus peut continuer à s'exécuter, mais l'application doit recréer l'activité à partir de zéro à l'aide d'un appel à onCreate.

  • Le système évince votre application de la mémoire, puis l'utilisateur la relance. Le processus et l'activité doivent redémarrer, mais la tâche peut bénéficier du groupe d'états d'instances enregistrés transmis à onCreate.

Démarrage à chaud

Un démarrage à chaud de votre application nécessite moins d'efforts qu'un démarrage à froid. Lors d'un démarrage à chaud, le système met l'activité hôte de votre application au premier plan. Si l'intégralité de l'UI de votre application est toujours en mémoire, l'application n'a pas besoin de répéter l'initialisation des objets, l'initialisation de l'UI et l'affichage.

Toutefois, si une partie de la mémoire est définitivement vidée à la suite d'événements de nettoyage, tels que onTrimMemory, ces objets doivent être recréés en réponse au démarrage à chaud.

Le démarrage à chaud présente le même comportement à l'écran que le démarrage à froid : Le processus système affiche un écran vide jusqu'à ce que l'application ait fini d'effectuer le rendu de l'activité.

Figure 1. Schéma représentant les différents états de démarrage et leurs processus respectifs, chaque état commençant par le premier frame affiché.

Comment identifier le démarrage de l'application dans Perfetto

Pour déboguer les problèmes de démarrage de l'application, il est utile de déterminer exactement ce qui est inclus dans la phase de démarrage de l'application. Pour identifier toute la phase de démarrage de l'application dans Perfetto, procédez comme suit :

  1. Dans Perfetto, recherchez la ligne contenant la métrique dérivée des démarrages de l'application Android. Si vous ne la voyez pas, essayez de capturer une trace à l'aide de l'application de traçage système sur l'appareil.

    Figure 2. Segment des métriques dérivées des démarrages de l'application Android dans Perfetto.
  2. Cliquez sur le segment associé, puis appuyez sur m pour le sélectionner. Des crochets apparaissent autour du segment et indiquent la durée du processus. La durée est également affichée dans l'onglet Current selection (Sélection actuelle).

  3. Épinglez la ligne des démarrages de l'application Android en cliquant sur l'icône en forme de punaise, qui s'affiche lorsque vous maintenez le pointeur sur la ligne.

  4. Faites défiler l'écran jusqu'à la ligne contenant l'application en question, puis cliquez sur la première cellule pour développer la ligne.

  5. Effectuez un zoom avant sur le thread principal, généralement en haut, en appuyant sur w (appuyez respectivement sur s, a ou d pour effectuer un zoom arrière, vous déplacer vers la gauche ou vous déplacer vers la droite).

    Figure 3. Segment des métriques dérivées des démarrages de l'application Android à proximité du thread principal de l'application.
  6. Le segment de métriques dérivées permet de voir plus facilement ce qui est inclus dans le démarrage de l'application, ce qui vous permet de poursuivre le débogage plus en détail.

Lorsque vous analysez une application Jetpack Compose, vous pouvez utiliser le traçage de la composition pour afficher des informations détaillées sur les performances de votre UI. Portez une attention particulière aux sections de trace dans le thread principal qui commencent par Choreographer#doFrame. Recherchez des tranches telles que Compose:recompose, Compose:layout et Compose:draw. Elles vous indiquent le temps passé par votre application à composer, mesurer, placer et dessiner des composants spécifiques.

Utiliser les métriques pour inspecter et améliorer les démarrages

Pour diagnostiquer correctement les performances liées au délai de démarrage, vous pouvez suivre les métriques qui indiquent le temps nécessaire au démarrage de votre application. Android vous propose plusieurs façons de vous signaler que votre application rencontre un problème et vous aide à le diagnostiquer. Android Vitals peut vous avertir que le problème se produit, et les outils de diagnostic peuvent vous aider à le diagnostiquer.

Avantages des métriques de démarrage

Android utilise les métriques Délai d'affichage initial (TTID) et Délai d'affichage total (TTFD) pour optimiser les démarrages d'application à froid et tiède. Android Runtime (ART) utilise les données de ces métriques pour précompiler efficacement le code afin d'optimiser les démarrages ultérieurs.

Des démarrages plus rapides entraînent une interaction plus durable des utilisateurs avec votre application, ce qui réduit le nombre d'instances de sortie anticipée, de redémarrage ou de navigation vers une autre application.

Android Vitals

Android Vitals peut vous aider à améliorer les performances de votre application en vous alertant via la Play Console lorsque les temps de démarrage de votre application sont trop longs.

Android Vitals considère que le délai de démarrage suivant de votre application est excessif :

  • le démarrage à froid prend cinq secondes ou plus ;
  • le démarrage tiède prend deux secondes ou plus ;
  • le démarrage à chaud prend 1,5 seconde ou plus.

Android Vitals utilise la métrique Délai d'affichage initial. Pour savoir comment Google Play collecte les données Android Vitals, consultez la documentation de la Play Console.

Délai d'affichage initial

Le délai d'affichage initial (TTID) correspond au temps nécessaire pour afficher le premier frame de l'interface utilisateur de l'application. Cette métrique mesure le temps nécessaire pour qu'une application produise sa première image, y compris l'initialisation du processus à froid, la création d'activités lors d'un démarrage à froid ou tiède, et l'affichage de la première image. Un TTID faible permet d'améliorer l'expérience utilisateur en permettant aux utilisateurs de voir rapidement le lancement de votre application. Le TTID est signalé automatiquement pour chaque application par le framework Android. Lorsque vous optimisez le démarrage d'une application, nous vous recommandons d'implémenter reportFullyDrawn pour obtenir des informations jusqu'au TTFD.

Le TTID est mesuré en tant que valeur temporelle représentant le temps écoulé total, qui comprend la séquence d'événements suivante :

  • Lancer le processus
  • Initialiser les objets
  • Créer et initialiser l'activité hôte
  • Initialisation de l'UI.
  • Afficher l'application pour la première fois

Récupérer le TTID

Pour trouver le TTID, recherchez dans l'outil de ligne de commande Logcat une ligne de sortie contenant une valeur appelée Displayed. Cette valeur est le TTID et ressemble à l'exemple suivant, dans lequel le TTID est de 3 s 534 ms :

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

Pour trouver le TTID dans Android Studio, désactivez les filtres dans la vue Logcat à partir du menu déroulant des filtres, puis recherchez le code temporel Displayed, comme illustré dans la figure 4. Cette opération est nécessaire, car c'est le serveur système, et non l'appli elle-même, qui gère ce journal.

Figure 4. Filtres désactivés et valeur Displayed dans Logcat.

La métrique Displayed dans la sortie Logcat ne capture pas systématiquement le temps nécessaire avant que toutes les ressources ne soient chargées et affichées. Elle exclut les ressources qui ne sont pas référencées dans la composition initiale (comme les données ou les images chargées de manière asynchrone) ou les ressources que l'application crée dans le cadre de l'initialisation de l'objet. Elle exclut ces ressources, car leur chargement est un processus intégré et ne bloque pas l'affichage initial de l'application. Pour en savoir plus sur les ressources, consultez Ressources dans Compose.

La ligne Displayed de la sortie Logcat contient parfois un champ supplémentaire indiquant la durée totale, comme dans l'exemple suivant :

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

Dans ce cas, la première mesure ne concerne que l'activité qui a été visualisée pour la première fois, généralement l'activité hôte. La mesure de la durée total commence au début du processus de l'application et peut inclure une autre activité démarrée en premier, mais qui n'affiche rien à l'écran. La mesure du temps total n'est affichée que s'il existe une différence entre l'activité unique et le temps total de démarrage.

Nous vous recommandons d'utiliser Logcat dans Android Studio. Toutefois, si vous n'utilisez pas Android Studio, vous pouvez également mesurer le TTID en exécutant votre application avec la commande adb du gestionnaire d'activités du shell. Exemple :

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

La métrique Displayed apparaît dans la sortie Logcat comme précédemment. La fenêtre de terminal affiche les éléments suivants :

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

Les arguments -c et -a sont facultatifs et vous permettent de spécifier une <category> et une <action>.

Délai d'affichage total

Le délai d'affichage total (TTFD) correspond au temps nécessaire pour qu'une application devienne interactive pour l'utilisateur. Il est indiqué comme le temps nécessaire pour afficher le premier frame de l'interface utilisateur de l'application, ainsi que le contenu qui se charge de manière asynchrone après l'affichage du frame initial. Il s'agit généralement du contenu principal chargé à partir du réseau ou du disque, comme indiqué par l'application. En d'autres termes, le TTFD inclut le TTID, ainsi que le temps nécessaire pour que l'appli soit utilisable. Un faible niveau du TTFD améliore l'expérience utilisateur en leur permettant d'interagir rapidement avec votre application.

Bien que le système puisse déterminer le TTID lorsque la fenêtre hôte affiche son premier frame, il ne peut pas déterminer automatiquement le TTFD. Étant donné que les applications chargent souvent leur contenu principal de manière asynchrone, le système ne sait pas quand l'application est réellement entièrement utilisable par l'utilisateur. Pour déterminer le TTFD, l'appli doit signaler au système lorsqu'elle atteint l'état d'affichage complet.

Récupérer le TTFD

Pour trouver le TTFD, signalez l'état d'affichage complet en appelant la méthode reportFullyDrawn du ComponentActivity. La méthode reportFullyDrawn indique lorsque l'application est complètement affichée et dans un état utilisable. Le TTFD correspond au temps écoulé entre le moment où le système reçoit l'intent de lancement de l'application et le moment où reportFullyDrawn est appelé. Si vous n'appelez pas reportFullyDrawn, aucune valeur TTFD n'est signalée.

Pour mesurer le TTFD, appelez reportFullyDrawn une fois que l'interface utilisateur et toutes les données sont complètement affichées. N'appelez pas reportFullyDrawn avant que la fenêtre de la première activité ne soit apparue et affichée comme mesurée par le système, car celui-ci indique alors la durée mesurée par le système. En d'autres termes, si vous appelez reportFullyDrawn avant que le système ne détecte le TTID, il signale à la fois le TTID et le TTFD comme la même valeur, et cette valeur correspond alors à celle du TTID.

Lorsque vous utilisez reportFullyDrawn, Logcat affiche une sortie semblable à l'exemple suivant, dans lequel le TTFD est de 1 s 54 ms :

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

La sortie Logcat inclut parfois une durée total, comme indiqué dans la section Délai d'affichage initial.

Si les délais d'affichage sont plus lents que vous le souhaitez, vous pouvez essayer d'identifier les goulots d'étranglement dans le processus de démarrage.

Vous pouvez utiliser reportFullyDrawn pour signaler l'état d'affichage complet dans les cas de base où vous savez que l'état d'affichage complet est atteint. Toutefois, dans les cas où les threads en arrière-plan doivent terminer le travail en arrière-plan avant que l'état d'affichage complet ne soit atteint, vous devez retarder reportFullyDrawn pour une mesure du TTFD plus précise. Pour savoir comment retarder reportFullyDrawn, consultez la section suivante.

Améliorer la précision du temps de démarrage

Si votre application effectue un chargement différé et que l'affichage initial n'inclut pas toutes les ressources, par exemple lorsque votre application récupère des images du réseau, vous pouvez retarder l'appel de reportFullyDrawn jusqu'à ce que votre application devienne utilisable. Vous pouvez ainsi inclure le remplissage de la liste dans votre analyse comparative.

Par exemple, si l'UI contient une liste dynamique, telle qu'une LazyColumn ou une LazyRow, elle peut être renseignée par une tâche en arrière-plan qui se termine après le premier affichage de la liste et, par conséquent, une fois que l'UI est marquée comme entièrement dessinée. Dans ce cas, le remplissage de la liste n'est pas inclus dans le benchmarking.

Pour inclure le remplissage de la liste dans votre analyse comparative, obtenez FullyDrawnReporter à l'aide de fullyDrawnReporter, et ajoutez-y un "rapporteur" dans le code de votre application. Libérez ce rapporteur lorsque la tâche en arrière-plan aura rempli la liste.

FullyDrawnReporter n'appelle pas la méthode reportFullyDrawn tant que tous les rapporteurs ajoutés ne sont pas libérés. En ajoutant un rapporteur, mais en ne le libérant qu'une fois le processus en arrière-plan terminé, vous vous assurez que les données de temps de démarrage incluent le temps de remplissage de la liste, sans modifier le comportement de l'application pour l'utilisateur. reportFullyDrawn n'est appelé que lorsque toutes les tâches sont terminées, quel que soit l'ordre.

Si votre application utilise Jetpack Compose, vous pouvez utiliser les API suivantes pour indiquer l'état entièrement dessiné :

  • ReportDrawn : indique que votre composable est immédiatement prêt à interagir.
  • ReportDrawnWhen : utilise un prédicat, comme list.count > 0, pour indiquer à quel moment votre composable sera prêt à interagir.
  • ReportDrawnAfter : utilise une méthode de suspension qui, lorsqu'elle se termine, indique que votre composable est prêt à interagir.

L'exemple suivant montre comment exécuter plusieurs tâches en arrière-plan simultanément, chacune enregistrant son propre rapport :

class MainActivity : ComponentActivity() {

    sealed interface ActivityState {
        data object LOADING : ActivityState
        data object LOADED : ActivityState
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            var activityState by remember {
                mutableStateOf(ActivityState.LOADING as ActivityState)
            }
            fullyDrawnReporter.addOnReportDrawnListener {
                activityState = ActivityState.LOADED
            }
            ReportFullyDrawnTheme {
                when(activityState) {
                    is ActivityState.LOADING -> {
                        // Display the loading UI.
                    }
                    is ActivityState.LOADED -> {
                        // Display the full UI.
                    }
                }
            }
            SideEffect {
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
                fullyDrawnReporter.addReporter()
                lifecycleScope.launch(Dispatchers.IO) {
                    // Perform the background operation.
                    fullyDrawnReporter.removeReporter()
                }
            }
        }
    }
}
Identifier les goulots d'étranglement

Pour identifier les goulots d'étranglement, vous pouvez utiliser le Profileur de processeur Android Studio. Pour en savoir plus, consultez la section Inspecter l'activité du processeur avec le Profileur de processeur.

Vous pouvez également obtenir des renseignements sur les goulots d'étranglement potentiels grâce au traçage intégré dans les méthodes onCreate de vos applications et activités. Pour en savoir plus sur le traçage intégré, consultez la documentation sur les fonctions Trace et la présentation du traçage système.

Résoudre les problèmes courants

Cette section traite de plusieurs problèmes qui affectent souvent les performances de démarrage des applications. Ces problèmes concernent principalement l'initialisation des objets d'application et d'activité, ainsi que le chargement des écrans.

Initialisation d'application à forte charge

Les performances de lancement peuvent être affectées lorsque votre code ignore l'objet Application et exécute un travail à forte charge ou une logique complexe lors de l'initialisation de cet objet. Votre application peut perdre du temps au démarrage si les sous-classes Application effectuent des initialisations qui ne sont pas nécessaires à ce stade.

Certaines initialisations peuvent être complètement inutiles, telles que l'initialisation des informations d'état pour l'activité principale lorsque l'application est démarrée en réponse à un intent. Avec un intent, l'application n'utilise qu'un sous-ensemble des données d'état précédemment initialisées.

Lors de l'initialisation de l'application, d'autres défis incluent les événements de récupération de mémoire à impact élevé ou en quantité importante, ou les opérations d'E/S sur le disque exécutées simultanément à l'initialisation, ce qui bloque encore davantage le processus d'initialisation. La récupération de mémoire est particulièrement importante pour l'environnement d'exécution Dalvik. L'environnement d'exécution Art exécute la récupération de mémoire en même temps, ce qui réduit l'impact de cette opération.

Diagnostiquer le problème

Vous pouvez utiliser le traçage de méthode ou le traçage intégré pour essayer de diagnostiquer le problème.

Traçage de méthode

L'exécution du Profileur de processeur révèle que la méthode callApplicationOnCreate appelle votre méthode com.example.customApplication.onCreate. Si l'outil montre que l'exécution de ces méthodes prend beaucoup de temps, vous devez examiner les tâches à effectuer de plus près.

Traçage intégré

Utilisez le traçage intégré pour identifier les causes probables de ces problèmes, notamment :

  • La fonction onCreate initiale de votre application
  • Tout objet Singleton global initialisé par votre application
  • Toute opération d'E/S sur le disque, désérialisation ou boucle serrée qui peut se produire durant le goulot d'étranglement

Les solutions au problème

Que le problème soit dû à des initialisations inutiles ou à des opérations d'E/S sur le disque, l'initialisation différée est la solution. En d'autres termes, n'initialisez que les objets qui sont nécessaires immédiatement. Au lieu de créer des objets statiques globaux, passez à un modèle Singleton où l'application initialise les objets uniquement la première fois qu'elle en a besoin.

Envisagez également d'utiliser un framework d'injection de dépendances comme Hilt, qui crée des objets et des dépendances lors de leur première injection.

Si votre application utilise des fournisseurs de contenu pour initialiser les composants de l'application au démarrage, envisagez plutôt d'utiliser la bibliothèque de démarrage d'application.

Initialisation d'activité à forte charge

La création d'activités implique souvent d'importants efforts. Il est souvent possible d'optimiser cette tâche afin d'améliorer les performances. Ces problèmes courants sont les suivants :

  • Initialisation d'une UI volumineuse ou complexe.
  • Initialisation lourde dans les composables.
  • Blocage de la visualisation à l'écran sur le disque ou l'E/S réseau
  • Chargement et décodage des bitmaps
  • Trame des objets VectorDrawable
  • Initialisation d'autres sous-systèmes de l'activité hôte de l'application.

Diagnostiquer le problème

Dans ce cas, le traçage de méthode et le traçage intégré peuvent également s'avérer utiles.

Traçage de méthode

Lorsque vous utilisez le Profileur de processeur, faites attention aux constructeurs de sous-classes Application et aux méthodes com.example.customApplication.onCreate de votre application.

Si l'outil montre que l'exécution de ces méthodes prend beaucoup de temps, vous devez examiner les tâches à effectuer de plus près.

Traçage intégré

Utilisez le traçage intégré pour identifier les causes probables de ces problèmes, notamment :

  • La fonction onCreate initiale de votre application
  • Tout objet Singleton global qu'elle initialise
  • Toute opération d'E/S sur le disque, désérialisation ou boucle serrée qui peut se produire durant le goulot d'étranglement

Les solutions au problème

Il existe de nombreux goulots d'étranglement potentiels, mais voici deux problèmes courants et leurs solutions :

  • Plus la hiérarchie de l'UI est grande, plus l'application met du temps à l'initialiser. Pour résoudre ce problème, procédez comme suit :
    • Aplatissez la hiérarchie de votre UI en réduisant les composables redondants ou imbriqués.
    • Évitez les compositions et recompositions inutiles au lancement.
    • Différez la composition de l'UI non critique.
  • Initialiser l'ensemble de vos ressources sur le thread principal peut également ralentir le démarrage. Pour résoudre ce problème :
    • Déplacez l'initialisation de toutes les ressources afin que l'application puisse l'effectuer de manière différée sur un thread différent.
    • Chargez et affichez d'abord votre UI avec des données d'espace réservé, puis mettez à jour les propriétés visuelles qui dépendent de bitmaps et d'autres ressources.

Pour en savoir plus sur la recomposition, consultez Recomposition et Obtenir le nombre de recompositions.

Écrans de démarrage personnalisés

Le démarrage peut prendre plus de temps si vous avez déjà utilisé l'une des méthodes suivantes pour implémenter un écran de démarrage personnalisé sous Android 11 (niveau d'API 30) ou version antérieure :

  • Utilisation de l'attribut de thème windowDisablePreview pour désactiver l'écran vierge initial affiché par le système lors du lancement
  • Utilisation d'une Activity dédiée

À partir d'Android 12, la migration vers l'API SplashScreen est requise. Cette API accélère le démarrage et vous permet d'ajuster votre écran de démarrage comme suit :

De plus, avec la bibliothèque de compatibilité, vous pouvez rétroporter l'API SplashScreen, ce qui permet d'activer la rétrocompatibilité et de créer une apparence cohérente pour les écrans de démarrage, quelle que soit la version d'Android.

Pour en savoir plus, consultez le guide de migration des écrans de démarrage.