Jank pour les applications mobiles — ce que c'est, causes et solutions

Auteur : IT Sectr Publié le : 2026-04-01 Temps de lecture : 10 min

Jank est un terme qui désigne des saccades notables ou des « bégaiements » dans l'animation de l'interface causés par le saut de trames individuelles. Dans les applications mobiles, Jank se produit lorsque le temps de rendu d'une trame dépasse le budget alloué par la fréquence de rafraîchissement de l'écran. Selon Android Developers, 2025, Jank est la principale cause de la sensation subjective de « lenteur » — une application peut être fonctionnellement parfaite, mais l'utilisateur la perçoit comme lente en raison d'un FPS instable.

Points clés

  • Jank — trames perdues qui se manifestent par des saccades d'animation.
  • La cause principale est le dépassement du budget de temps par trame (16,6 ms pour 60 FPS).
  • Jank survient en raison d'un Layout lourd, d'une longue GC, d'un blocage du thread principal ou d'un overdraw.
  • Pour le diagnostic, on utilise FrameTimeline (Android) et Instruments (iOS).
  • L'élimination de Jank augmente le NPS et la rétention des utilisateurs de 15 à 25%.

Qu'est-ce que Jank

Jank est un terme d'infographie qui désigne un défaut visuel où l'animation se déplace par à-coups au lieu de glisser en douceur. Dans le développement mobile, Jank se mesure comme le nombre de trames perdues (skipped frames) par unité de temps. Si le système ne parvient pas à préparer une trame à temps pour le VSync, l'écran répète la trame précédente — une pause de 16,6 ms se produit à 60 Hz. Une seule trame perdue peut passer inaperçue, mais une série de 3 à 5 trames perdues consécutives crée une sensation de « saccade » durant 50 à 80 ms, que l'utilisateur perçoit clairement.

Jank est particulièrement critique pour les animations qui doivent fonctionner à vitesse constante : défilement de fils d'actualité, animation d'ouverture de menu, effets de parallaxe, transitions entre écrans. Selon une étude UX de Google (2024), une application avec un taux de Jank supérieur à 3% des sessions de défilement reçoit 22% d'avis une étoile de plus qu'une application avec un taux inférieur à 0,5%. L'outil Android Vitals suit automatiquement Jank et le classe par sévérité : modéré, sévère et critique.

Causes principales de Jank

Les causes de Jank se divisent en plusieurs catégories. La première est Layout Jank : causée par des appels fréquents à requestLayout() en raison de changements de taille des Views, d'animations LayoutTransition ou de chargement dynamique de contenu. Chaque appel requestLayout déclenche Measure + Layout pour toute la sous-arborescence des Views, ce qui peut prendre 5 à 30 ms. La deuxième est Draw Jank : liée à l'overdraw et à l'utilisation de drawables lourds. La troisième est Thread Jank : blocage du thread principal dû à des opérations synchrones — chargement de fichiers, opérations base de données sur le thread principal, décodage de Bitmap.

La quatrième catégorie est GC Jank : garbage collection (GC) dans ART/Dalvik ou Swift ARC. Lorsque de nombreux objets s'accumulent dans le tas, le GC déclenche une pause Stop-The-World de 5 à 15 ms. Sous Android, les pauses GC surviennent le plus souvent lors d'allocations fréquentes dans des boucles : création d'objets dans onDraw(), allocation dans des adaptateurs, expressions lambda inutilisées. La cinquième est IPC Jank : communication interprocessus (ContentProvider, Binder) sur le thread principal. La sixième est Rendering Jank : rendu GPU lent dû à des shaders non optimaux ou à des textures de grande taille.

Type de JankCauseDurée typiqueOutil de détection
LayoutrequestLayout, relayout5–30 msPerfetto, Systrace
DrawOverdraw, drawables lourds3–20 msGPU Profiling
ThreadBlocage du thread principal10–200 msAndroid Studio Profiler
GCGarbage Collection5–15 msMemory Profiler
RenderingCharge GPU10–50 msGPU Tracer, Xcode GPU

Diagnostic de Jank sous Android

Sous Android, le diagnostic de Jank commence par la trace système Perfetto. Perfetto enregistre l'activité de tous les threads, du CPU, du GPU et de l'ordonnanceur. Un indicateur clair de Jank sont les lignes Choreographer.doFrame et Choreographer.doCallbacks : si l'intervalle entre deux appels consécutifs à doFrame dépasse 16,6 ms, une trame a été perdue. Perfetto montre la cause exacte — quel appel système, verrou ou GC a provoqué le retard. Dans Android Studio Profiler, une fonctionnalité similaire est disponible via CPU Profiler.

Pour la détection automatique de Jank en production, on utilise FrameMetricsAggregator — une API qui collecte des statistiques pour chaque trame et les agrège par session. Dans Android 12+, PerformanceHintManager est apparu — une API pour donner des indices au système sur la fréquence d'images cible. Si l'application indique qu'elle fonctionne dans un scénario 120 FPS, le système peut augmenter la fréquence CPU/GPU pour prévenir Jank. Pour une journalisation simple de toutes les trames perdues, il suffit de s'abonner à Choreographer.FrameCallback.

Journalisation de Jank via Choreographer

Le code Kotlin s'abonne à Choreographer.FrameCallback et journalise chaque trame perdue avec la durée du retard. Le callback est invoqué à chaque VSync.

kotlin
class JankDetector {

    private val frameBudget = 16_666_666L
    private var previousFrameTime = 0L

    private val callback =
        Choreographer.FrameCallback { currentTime ->
            if (previousFrameTime != 0L) {
                val frameDuration =
                    currentTime - previousFrameTime
                val skippedFrames =
                    (frameDuration / frameBudget) - 1
                if (skippedFrames > 0) {
                    Log.w("Jank",
                        "Skipped $skippedFrames frames")
                }
            }
            previousFrameTime = currentTime
            Choreographer.getInstance()
                .postFrameCallback(this)
        }

    fun start() {
        Choreographer.getInstance()
            .postFrameCallback(callback)
    }
}

Diagnostic de Jank sous iOS

Sous iOS, le diagnostic de Jank s'effectue via Instruments avec le modèle Core Animation. Instruments affiche le FPS en temps réel, le nombre de rendus hors écran et les tests de hit. Les principaux indicateurs de Jank sous iOS : barres rouges dans la chronologie Core Animation (dépassement du budget de trame), valeur élevée de Renderer (indiquant un rendu hors écran) et FPS bas. Pour la surveillance en production, MetricKit collecte des rapports avec la métrique MXAnimatoryMetric, qui inclut le FPS moyen, le temps de trame P50 et P95.

Le diagnostic natif de Jank sous iOS inclut CADisplayLink avec vérification du timestamp et du targetTimestamp. Si le timestamp actuel est significativement en retard par rapport au targetTimestamp, une ou plusieurs trames ont été perdues. Apple recommande également d'utiliser os_signpost pour le profilage personnalisé : placer un signpost-interval au début et à la fin du rendu de la trame et vérifier dans Instruments quels intervalles dépassent 16,6 ms. Dans SwiftUI, UIView.invalidateIntrinsicContentSize est utilisé pour le diagnostic de Jank — les appels fréquents à cette méthode indiquent un Layout instable.

CADisplayLink pour la détection de Jank

Le code Swift détecte les trames perdues via CADisplayLink. Si la différence entre le timestamp et le targetTimestamp dépasse 16,6 ms, Jank est enregistré.

swift
class JankMonitor {

    private var displayLink: CADisplayLink?
    private var totalJank = 0

    func start() {
        displayLink = CADisplayLink(
            target: self,
            selector: #selector(detectJank)
        )
        displayLink?.add(to: .current,
            forMode: .common)
    }

    @objc
    private func detectJank() {
        guard let link = displayLink else { return }
        let delay = link.targetTimestamp
            - link.timestamp
        if delay > 0.0167 {
            totalJank += 1
        }
    }
}

Outils de profilage de Jank

Pour le profilage de Jank, on utilise à la fois des outils intégrés au système d'exploitation et des SDK tiers. Sous Android, l'outil clé est Perfetto (qui a remplacé Systrace). Perfetto permet d'enregistrer des traces jusqu'à 30 secondes et de les analyser via l'interface web ui.perfetto.dev. Il montre une chronologie précise avec l'activité de Choreographer, les threads de rendu (RenderThread) et le GPU. Pour l'analyse détaillée des problèmes GPU, on utilise AGI (Android GPU Inspector), qui montre non seulement le temps de trame mais aussi la charge de blocs GPU spécifiques — shaders, rasterizer, unité de texture.

Sous iOS, l'équivalent est Instruments avec les modèles Core Animation, Metal System Trace et GPU Driver. Core Animation montre le FPS et le temps de trame, Metal System Trace montre le travail du GPU jusqu'à chaque draw call. Pour le profilage sur des appareils réels sous charge, on utilise Firebase Performance (collecte la métrique Screen Rendering) et Sentry(capture la stack trace en cas de Jank). La nouvelle API Android 15 Performance Hint permet au développeur d'indiquer au système quelles trames sont importantes et de recevoir des avertissements du système lorsque Jank est proche.

FrameMetricsAggregator en production

Le code Kotlin utilise FrameMetricsAggregator pour collecter des statistiques par trame sur une session. Après l'arrêt de l'agrégateur, le nombre de trames perdues est affiché.

kotlin
class JankAggregator(private val activity: Activity) {

    private val aggregator = FrameMetricsAggregator()

    fun startCollection() {
        aggregator.add(activity.window)
    }

    fun stopAndReport() {
        aggregator.remove()
        val result = aggregator.getMetrics()
        val totalFrames = result
            ?.get(FrameMetrics.TOTAL_DURATION)
            ?.size ?: 0
        val jankFrames = result
            ?.get(FrameMetrics.TOTAL_DURATION)
            ?.count { it > 16_666_666L} ?: 0
        Log.d("JankReport",
            "Jank ratio: \${jankFrames * 100 / totalFrames}%")
    }
}

Méthodes pour éliminer les saccades d'images

L'élimination de Jank nécessite une combinaison de techniques selon son type. Pour Layout Jank : remplacer les hiérarchies profondes par ConstraintLayout/Compose/SwiftUI, utiliser les balises merge, éviter requestLayout dans les animations. Pour Draw Jank : utiliser Debug GPU Overdraw pour trouver l'overdraw 4x+, remplacer les drawables lourds par des vecteurs (VectorDrawable/PDF), utiliser les hardware layers avec prudence — ils accélèrent le rendu mais consomment plus de mémoire GPU. Pour Thread Jank : déplacer toutes les opérations d'E/S, le travail avec la base de données et le décodage Bitmap vers des threads en arrière-plan, utiliser Kotlin Coroutines avec le bon Dispatcher ou RxJava avec Schedulers.io().

Pour GC Jank : minimiser les allocations dans onDraw() et getView(), utiliser des pools d'objets (ObjectPool), remplacer for-each par for indexé, utiliser des data class immuables en Kotlin avec copy() avec précaution — copy crée un nouvel objet. Pour IPC Jank : initialiser ContentProvider paresseusement via App Startup, déplacer les appels Binder vers un thread en arrière-plan. Pour Rendering Jank : réduire la taille des textures à la résolution maximale de l'écran, utiliser la compression ASTC ou ETC2, éviter les compilations de shaders excessives (compiler les shaders à l'avance). Une solution complète est l'exécution régulière de profilage Perfetto/Instruments dans le CI et le suivi des régressions de Jank.

Motif Anti-Jank : Async Layout

Le code Kotlin démontre le chargement asynchrone des données à l'écran après reportFullyDrawn, afin que le travail lourd ne bloque pas la première trame. Le callback est invoqué après que l'utilisateur voit l'interface.

kotlin
class JankSafeLoader {

    suspend fun loadAfterFirstFrame(
        activity: Activity
    ) {
        // garantir que la première trame est déjà rendue
        if (Build.VERSION.SDK_INT >= 29) {
            activity.reportFullyDrawn()
        }

        // chargement lourd — après la première trame
        withContext(Dispatchers.IO) {
            val data = fetchHeavyData()
            withContext(Dispatchers.Main) {
                updateUI(data)
            }
        }
    }
}

Questions fréquentes

Qu'est-ce que Jank dans les applications mobiles ?

Jank sont des trames de rendu perdues qui se manifestent par des saccades ou à-coups notables dans l'animation. Cela se produit lorsque le temps de préparation de la trame dépasse le budget de temps (16,6 ms pour 60 FPS).

Quelles sont les principales causes de Jank ?

Layout Jank (requestLayout fréquent), Draw Jank (overdraw), Thread Jank (blocage du thread principal), GC Jank (garbage collection), IPC Jank (appels Binder) et Rendering Jank (shaders lourds).

Comment diagnostiquer Jank sous Android ?

Utilisez Perfetto pour le tracing système, GPU Profiling pour l'analyse des phases de trame et FrameMetricsAggregator pour la surveillance en production. Dans Android Studio — CPU Profiler avec Deep Java Trace.

Comment mesurer Jank sous iOS ?

Via Instruments avec le modèle Core Animation ou Metal System Trace. Pour la production — MetricKit avec MXAnimatoryMetric. Programmatiquement — CADisplayLink en vérifiant la différence entre timestamp et targetTimestamp.

Quel pourcentage de Jank est considéré comme critique ?

Selon Google, un taux de Jank supérieur à 3% des sessions de défilement (3 défilements sur 100 contiennent une saccade) entraîne une augmentation de 22% des avis négatifs. Le taux cible est inférieur à 0,5% des sessions de défilement.

Résumé

  • Jank — trames perdues causant des saccades visibles dans l'animation des applications mobiles.
  • Causes principales : Layout Jank, Draw Jank, Thread Jank, GC Jank, IPC Jank et Rendering Jank.
  • Diagnostic de Jank sous Android — via Perfetto, GPU Profiling et FrameMetricsAggregator.
  • Diagnostic de Jank sous iOS — via Instruments, CADisplayLink et MetricKit.
  • L'élimination de Jank nécessite une combinaison de : hiérarchies plates, threads en arrière-plan, allocations minimisées, mise en cache.
  • Taux de Jank cible — moins de 0,5% des sessions de défilement avec saccades.
  • Un profilage régulier dans le CI prévient les régressions de performance avant qu'elles n'atteignent la production.

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