Performance dans le développement mobile : définition, métriques et comment l'améliorer

Auteur : IT Sectr Publié le : 2026-03-25 Temps de lecture : 12 min

Une application lente est la principale raison pour laquelle les utilisateurs suppriment des programmes. Des millisecondes de retard au démarrage ou lors du défilement d'une liste réduisent la rétention de dizaines de pour cent. La performance n'est pas seulement la vitesse, mais aussi la stabilité : absence d'ANR, de crashes et de fuites mémoire. Cet article couvre tous les aspects de la performance : de la gestion de la mémoire (GC, ARC) au profilage avec des outils. En savoir plus dans le guide officiel Android Performance.

Points clés

  • ANR et Crash sont les principaux ennemis de l'expérience utilisateur ; évités par les threads en arrière-plan
  • Fuites mémoire et Retain Cycle provoquent des crashes OOM ; résolus par des références faibles et des utilitaires
  • GC (Android) et ARC (iOS) sont des modèles de gestion mémoire ; comprendre leur fonctionnement est crucial
  • Profilage (Instruments, Android Profiler, LeakCanary) est une étape de développement obligatoire
  • Cold Start est la métrique de lancement la plus importante ; optimisation d'Application.onCreate et initialisation paresseuse
  • Taille de l'App — utiliser App Bundle, R8, VectorDrawable et WebP pour réduire la taille

Pourquoi l'application ralentit-elle ?

La performance de l'application est directement liée au jank — un retard notable entre l'action de l'utilisateur et la réponse de l'interface. Causes principales : blocage du thread principal (opérations lourdes sur le thread UI), redessins fréquents de la mise en page (overdraw), fuites mémoire (GC fréquent), algorithmes non optimaux (O(n²) sur de grands ensembles de données). Frame Rate (FPS) — nombre d'images par seconde. Pour une expérience confortable, il faut 60 FPS stables (Android) ou 120 FPS (iPhone Pro, iPad Pro). VSync synchronise le rendu avec la fréquence de rafraîchissement de l'écran.

Le jank se produit lorsque le rendu d'une seule image dépasse 16,6 ms (pour 60 FPS) ou 8,3 ms (pour 120 FPS). Le profilage GPU (Profile GPU Rendering sur Android, Core Animation sur iOS) montre quelles étapes du rendu prennent le plus de temps. Étapes principales : Layout (positionnement des éléments), Draw (dessin), Display (transfert au tampon d'images). Le problème le plus courant est l'inflation de la mise en page en XML, en particulier avec des ConstraintLayout imbriqués complexes.

Time-to-Interactive (TTI) — temps nécessaire à l'application pour être entièrement prête à interagir. Le TTI inclut le Cold Start, le chargement des données et l'initialisation des bibliothèques. Google recommande un TTI inférieur à 5 secondes, Apple — inférieur à 2 secondes pour les écrans principaux. Lazy Loading — technique de chargement différé du contenu et des bibliothèques, cruciale pour améliorer le TTI. Chez IT Sectr, nous utilisons l'initialisation paresseuse par défaut dans tous les projets.

ANR et Crash

ANR et Crash sont les principaux ennemis de la performance des applications mobiles. ANR (Application Not Responding) — boîte de dialogue sur Android qui apparaît si le thread principal est bloqué plus de 5 secondes. Causes : requêtes réseau synchrones sur le thread UI, travail avec la base de données sans coroutines, décodage de bitmap volumineux sans downsampling, deadlock sur le thread principal. La pile d'appels ANR est sauvegardée dans /data/anr/traces.txt et permet de déterminer l'emplacement exact du blocage.

Crash — arrêt inattendu de l'application. Sur Android — c'est une Exception (Java/Kotlin) ou un Signal (code natif). Sur iOS — NSException ou signal (EXC_BAD_ACCESS — accès à la mémoire libérée). Outils de Crash Reporting : Firebase Crashlytics, Sentry, BugSnag. Ils collectent la stacktrace, les données de l'appareil et les étapes de reproduction. Stack Overflow — débordement de la pile d'appels par récursion infinie. OutOfMemoryError — lorsque le tas (heap) est plein.

StrictMode — outil Android pour détecter les violations de sécurité des threads. Il permet de définir des règles : ThreadPolicy (interdire le disque/réseau sur le thread principal), VmPolicy (détecter les fuites d'Activity, SQLite, CloseGuard). StrictMode doit être activé uniquement dans les versions de débogage — en release, il ne doit pas fonctionner. Sur iOS, l'équivalent est Main Thread Checker (Xcode), qui détecte automatiquement les appels UIKit hors du thread principal.

Gestion de la mémoire (GC, ARC, Retain Cycle)

Fuites mémoire

Une fuite mémoire (Memory Leak) est une situation où un objet reste en mémoire alors que l'application ne l'utilise plus. Cela réduit directement les performances de l'application. Sur Android, le GC (Garbage Collection) ne peut pas collecter un objet s'il y a une référence forte vers lui. Causes typiques : références statiques à Activity, callbacks/observateurs non annulés, classes internes avec référence implicite à la classe externe, Handler avec des messages non nettoyés. LeakCanary — bibliothèque de détection automatique des fuites.

Retain Cycle (Cycle de rétention)

ARC (Automatic Reference Counting) — modèle de gestion de mémoire sur iOS. Chaque objet a un compteur de références (retain count). Lorsque le compteur atteint zéro, la mémoire est libérée. Un Retain Cycle se produit lorsque deux objets maintiennent des références fortes l'un vers l'autre (A → B et B → A). L'ARC ne mettra jamais les compteurs à zéro. Solution : références faibles (weak) ou sans propriétaire (unowned). Weak est automatiquement nullifiée (devient nil) lors de la libération de l'objet. Unowned n'est pas nullifiée mais garantit que l'objet est vivant.

GC vs ARC

GC (Garbage Collection) fonctionne sur Android (Java/Kotlin). Le GC interrompt périodiquement l'exécution (pause Stop-the-World) pour trouver et libérer les objets inatteignables. Déclencheur du GC : lorsque le tas (heap) atteint un certain pourcentage de remplissage. L'ARC fonctionne sur iOS (Swift/Objective-C) et n'a pas de pauses — les compteurs sont mis à jour atomiquement à chaque affectation. L'ARC est plus prévisible mais peut accumuler des opérations retain/release excessives en cas de fréquence d'affectation élevée.

Référence faible (Weak Reference) et référence forte (Strong Reference) — le type de référence détermine si le GC/ARC peut libérer l'objet. Strong Reference — l'objet ne sera pas collecté tant que cette référence existe. Weak Reference — le GC/ARC peut collecter l'objet ; la référence faible devient nil (en Swift/Java WeakReference). Unowned Reference (Swift) — n'est pas nullifiée lors de la libération ; y accéder après la mort de l'objet provoque un crash. Sur Android, java.lang.ref.WeakReference est utilisé pour les références faibles.

Exemple de détection de fuite sur Android avec LeakCanary :

kotlin
// Утечка: анонимный класс держит ссылку на Activity
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val handler = object : Handler(Looper.getMainLooper()) {
            override fun handleMessage(msg: Message) {
                // Используем `this@MainActivity`, сохраняя ссылку на Activity
                Log.d("TAG", "Handler received message")
            }
        }
        handler.sendEmptyMessageDelayed(0, 60000)
    }
}

// Исправление: статический Handler + WeakReference
class SafeHandler(activity: MainActivity) : Handler() {
    private val weakActivity =
        WeakReference(activity)

    override fun handleMessage(msg: Message) {
        weakActivity.get() ?: return
        Log.d("TAG", "Handler received message")
    }
}

Profilage (Instruments, Android Profiler)

Le profilage est le processus de mesure des performances de l'application : CPU, mémoire, réseau, consommation d'énergie. Sans profilage, l'optimisation aveugle est inutile — vous ne saurez pas quelle partie du code ralentit réellement.

Outil Plateforme Mesure Quand utiliser
Instruments (Time Profiler)iOSCPU, appels de fonction, temps d'exécutionOptimisation d'algorithmes, recherche de goulots d'étranglement
Instruments (Allocations)iOSMémoire, nombre d'objets, retain countsRecherche de fuites et consommation excessive de mémoire
Instruments (Leaks)iOSRetain cycles, fuites mémoireVérification régulière avant la release
Android Profiler (CPU)AndroidUtilisation CPU, activité des threads, tracesRecherche de blocages du thread principal
Android Profiler (Memory)AndroidHeap dump, suivi des allocationsRecherche de fuites, analyse d'objets
Android Profiler (Network)AndroidTrafic, vitesse, temps de requêteOptimisation des appels réseau
LeakCanaryAndroidDétection automatique des fuites mémoireÀ toutes les étapes du développement
StrictModeAndroidDisque/réseau sur le thread principal, fuitesBuild de débogage
Traceview / SystraceAndroidTraçage de méthodes, événements systèmeAnalyse approfondie de la latence

Instruments (Xcode) — l'outil le plus puissant pour iOS. Time Profiler montre quelles fonctions consomment le plus de CPU. Allocations suit la création et la libération d'objets. Leaks détecte automatiquement les retain cycles. Étapes du profilage : (1) lancer Instruments ; (2) sélectionner un modèle (Time Profiler pour CPU) ; (3) exécuter le scénario problématique ; (4) analyser la pile d'appels — la colonne la plus large est la fonction la plus « chaude ».

Android Profiler est intégré à Android Studio (View → Tool Windows → Profiler). CPU Profiler montre la charge de chaque thread. Memory Profiler — heap dump et suivi des allocations. Network Profiler — toutes les requêtes HTTP avec timings. Energy Profiler — consommation d'énergie : WakeLock, Location, Network. Pour un traçage détaillé, on utilise Systrace (Android 10+) ou Perfetto — traçage système avec une précision à la microseconde.

Démarrage de l'application (Cold/Warm/Hot Start)

Le démarrage de l'application est l'un des indicateurs de performance clés. Il se divise en trois types : Cold Start — l'application démarre à partir de zéro : création du processus, Application.onCreate (Android) / AppDelegate.applicationDidFinishLaunching (iOS), chargement des classes, initialisation des bibliothèques. Warm Start — le processus existe, mais l'Activity/ViewController est détruit (par exemple, lors de la rotation de l'écran ou du retour de la mémoire). Hot Start — l'Activity/ViewController est en mémoire, l'application est simplement affichée (passage depuis une autre application).

Le Cold Start est la métrique la plus importante. Sur Android, il inclut : (1) launch Activity — chargement XML, initialisation de la View ; (2) première image — temps jusqu'au premier rendu. Google recommande : launch Activity < 200 ms, première image < 500 ms, TTI < 5 secondes. Optimisation du Cold Start : réduire Application.onCreate (coroutines pour l'initialisation paresseuse), utiliser SplashScreen API (Android 12+), différer l'initialisation des bibliothèques (WorkManager, DI), supprimer les ContentProviders inutiles.

Sur iOS, le Cold Start inclut : chargement du binaire Mach-O, dyld (éditeur de liens dynamique), initialisation du runtime Objective-C, délégué d'application, premier contrôleur. Chrome Custom Tabs (Android) et Universal Links (iOS) — technologies pour ouvrir rapidement du contenu externe dans l'application sans Cold Start complet. Il est recommandé de tester le Cold Start sur des appareils réels de milieu de gamme.

Optimisation de la taille

La taille de l'application est un facteur de performance pour l'installation et les mises à jour. Elle affecte la conversion : chaque 10 MB réduit la conversion de 1 %. Google Play recommande une taille d'APK inférieure à 150 MB ; l'App Store — inférieure à 200 MB (réseaux cellulaires — 100 MB). Principales méthodes d'optimisation : compression d'images (WebP au lieu de PNG économise 25-35 %), vectorisation (VectorDrawable sur Android, SF Symbols sur iOS), suppression du code inutilisé (R8/ProGuard), suppression des ressources inutilisées (lint → unused resources).

App Bundle (Android) — format de publication où Google Play génère un APK optimisé pour chaque appareil. App Bundle réduit la taille du téléchargement de 20 à 40 %. Dynamic Delivery — modules téléchargés à la demande (on-demand feature modules). Sur iOS, l'équivalent est On-Demand Resources (ODR) : ressources téléchargées après le premier lancement (niveaux de jeu, vidéos).

Lazy Loading — technique où les modules et bibliothèques ne sont pas chargés au démarrage mais chargés selon les besoins. Split APK (Android) et App Slicing (iOS) — division de l'application en segments d'architecture : arm64-v8a, x86_64. Optimisation de la taille de l'App — un processus continu : analysez la composition de l'APK (Analyze APK dans Android Studio), supprimez les icônes en double, utilisez SVG au lieu de plusieurs densités PNG. Chez IT Sectr, nous incluons la vérification de la taille du build dans le CI/CD pour chaque MR.

Questions fréquentes

Qu'est-ce que l'ANR et comment l'éviter ?

ANR (Application Not Responding) — boîte de dialogue qui apparaît sur Android si le thread principal est bloqué plus de 5 secondes. Pour éviter l'ANR, déplacez toutes les opérations lourdes (réseau, base de données, traitement de fichiers) vers des threads en arrière-plan. L'équivalent sur iOS est frozen UI, lorsque l'application cesse de répondre aux touches.

Qu'est-ce qu'une fuite mémoire et un Retain Cycle ?

Une fuite mémoire se produit lorsqu'un objet ne peut pas être libéré parce que des références vers lui existent encore. Un Retain Cycle est une situation en iOS/Objective-C où deux objets se référencent mutuellement (A → B → A) et l'ARC ne peut libérer aucun des deux. Solution : références weak/unowned et nettoyage opportun des callbacks.

Quels outils utiliser pour le profilage ?

Pour iOS : Instruments (Time Profiler, Allocations, Leaks). Pour Android : Android Profiler (CPU, Memory, Network), LeakCanary (fuites mémoire), StrictMode (violations de threads). Il est recommandé de combiner le profilage pendant le développement et l'intégration.

En quoi le Cold Start diffère-t-il du Warm Start et du Hot Start ?

Cold Start — l'application démarre à partir de zéro : le processus est créé, les classes sont chargées, Application.onCreate s'exécute. Warm Start — le processus existe mais l'Activity/ViewController est recréée. Hot Start — l'Activity/ViewController est déjà en mémoire, simplement affichée. Cold Start est le plus lent (1-5 secondes) et est critique pour l'expérience utilisateur.

Comment réduire la taille d'une application mobile ?

Méthodes principales : supprimer les ressources et le code inutilisés (utiliser R8/ProGuard), vectoriser les images (VectorDrawable, SF Symbols), compresser PNG/WebP (Android), utiliser App Bundle au lieu d'APK, supprimer les bibliothèques inutiles, utiliser Lazy Loading pour les modules. L'optimisation de la taille peut réduire l'APK de 40 à 60 %.

Résumé

  • ANR et Crash — les principaux problèmes de stabilité ; résolus par des threads en arrière-plan et des rapports de crash
  • Fuites mémoire et Retain Cycle — causes principales d'OOM ; résolues par des références faibles et LeakCanary
  • GC (pauses Stop-the-World) vs ARC (pas de pauses mais retain cycles) — différents modèles mémoire
  • Profilage — étape obligatoire : Instruments (iOS), Android Profiler, LeakCanary, StrictMode
  • Cold Start — métrique clé ; optimiser Application.onCreate et initialisation paresseuse
  • App Bundle et WebP/VectorDrawable — principaux outils pour réduire la taille de 20 à 60 %
  • La performance est un processus continu, pas une activité ponctuelle ; intégrez les métriques dans le CI/CD

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