Jank voor mobiele apps — wat is het, oorzaken en verhelping

Auteur: IT Sectr Gepubliceerd: 2026-04-01 Leestijd: 10 min

Jank — is een term die merkbare haperingen of “stotteren” van de interface-animatie aanduidt, veroorzaakt door het overslaan van afzonderlijke frames. In mobiele apps treedt Jank op wanneer de renderingtijd van een frame het budget overschrijdt dat is toegewezen door de verversingssnelheid van het display. Volgens Android Developers, 2025 is Jank de belangrijkste oorzaak van het subjectieve gevoel van “vertraging” — de app kan functioneel perfect zijn, maar de gebruiker ervaart hem als traag vanwege een instabiele FPS.

Belangrijkste punten

  • Jank — overgeslagen frames, merkbaar als animatiehaperingen.
  • Hoofdoorzaak — overschrijding van het tijdbudget per frame (16.6 ms voor 60 FPS).
  • Jank ontstaat door zware Layout, lange GC, blokkering van de main thread of overdraw.
  • Voor diagnose worden FrameTimeline (Android) en Instruments (iOS) gebruikt.
  • Het verhelpen van Jank verhoogt NPS en gebruikersretentie met 15–25%.

Wat is Jank

Jank — is een term uit de computergrafiek die een visueel defect aanduidt waarbij de animatie schokkerig beweegt in plaats van vloeiend te glijden. In mobiele ontwikkeling wordt Jank gemeten als het aantal overgeslagen frames (skipped frames) per tijdseenheid. Als het systeem er niet in slaagt een frame te prepareren vóór het VSync-moment, herhaalt het display het vorige frame — er ontstaat een pauze van 16.6 ms bij 60 Hz. Eén overgeslagen frame kan onmerkbaar zijn, maar een reeks van 3–5 opeenvolgende overgeslagen frames creëert een gevoel van “vertraging” van 50–80 ms, dat de gebruiker duidelijk registreert.

Jank is vooral kritisch voor animaties die met constante snelheid moeten werken: scrollen van lijsten, animatie van menu-openen, parallax-effecten, overgangen tussen schermen. Volgens UX-onderzoek van Google (2024) krijgt een app met een Jank-indicator van meer dan 3% scrollsessies 22% meer éénsterrecensies dan een app met een indicator van minder dan 0.5%. De tool Android Vitals volgt automatisch Jank en classificeert het op severity: moderate, severe en critical.

Belangrijkste oorzaken van Jank

De oorzaken van Jank zijn onderverdeeld in verschillende categorieën. De eerste — Layout Jank: veroorzaakt door frequente requestLayout()-aanroepen door veranderingen in View-afmetingen, LayoutTransition-animaties of dynamisch laden van inhoud. Elke requestLayout-aanroep start Measure + Layout voor de gehele View-subboom, wat 5–30 ms kan duren. De tweede — Draw Jank: gerelateerd aan overdraw en het gebruik van zware drawables. De derde — Thread Jank: blokkering van de main thread door synchrone bewerkingen — bestanden laden, werken met de database op de hoofdthread, Bitmap-decodering.

De vierde categorie — GC Jank: garbage collection in ART/Dalvik of Swift ARC. Wanneer zich veel objecten ophopen in de heap, start GC een Stop-The-World-pauze van 5–15 ms. Op Android treden GC-pauzes het vaakst op bij frequente allocaties in lussen: objecten maken in onDraw(), allocaties in adapters, ongebruikte lambda-expressies. De vijfde — IPC Jank: interprocescommunicatie (ContentProvider, Binder) op de hoofdthread. De zesde — Rendering Jank: trage GPU-rendering door niet-optimale shaders of texturen van grote afmetingen.

Type JankOorzaakTypische duurZoektool
LayoutrequestLayout, relayout5–30 msPerfetto, Systrace
DrawOverdraw, zware drawable3–20 msGPU Profiling
ThreadBlokkering main thread10–200 msAndroid Studio Profiler
GCGarbage Collection5–15 msMemory Profiler
RenderingGPU-belasting10–50 msGPU Tracer, Xcode GPU

Diagnose van Jank in Android

In Android begint de diagnose van Jank met de systeemtrace Perfetto. Perfetto registreert de activiteit van alle threads, CPU, GPU en planner. Een duidelijke indicator van Jank zijn de regels Choreographer.doFrame en Choreographer.doCallbacks: als het interval tussen twee opeenvolgende doFrame-aanroepen meer dan 16.6 ms bedraagt, is het frame overgeslagen. Perfetto toont de exacte oorzaak — welke system call, lock of GC de vertraging veroorzaakte. In Android Studio Profiler is vergelijkbare functionaliteit beschikbaar via CPU Profiler.

Voor automatische detectie van Jank in productie wordt FrameMetricsAggregator gebruikt — een API die statistieken per frame verzamelt en aggregeert per sessie. In Android 12+ is PerformanceHintManager verschenen — een API voor hints aan het systeem over de beoogde framesnelheid. Als de app aangeeft in een 120 FPS-scenario te werken, kan het systeem de CPU/GPU-frequentie verhogen om Jank te voorkomen. Voor eenvoudige logging van alle overgeslagen frames is het voldoende om je te abonneren op Choreographer.FrameCallback.

Jank loggen via Choreographer

Kotlin-code abonneert zich op Choreographer.FrameCallback en logt elk overgeslagen frame met vermelding van de vertragingsduur. De callback wordt bij elke VSync aangeroepen.

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",
                        "$skippedFrames frames overgeslagen")
                }
            }
            previousFrameTime = currentTime
            Choreographer.getInstance()
                .postFrameCallback(this)
        }

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

Diagnose van Jank in iOS

In iOS wordt de diagnose van Jank uitgevoerd via Instruments met de Core Animation-sjabloon. Instruments toont realtime FPS, het aantal offscreen-renders en hit-tests. De belangrijkste indicatoren van Jank in iOS: rode kolommen op de Core Animation-tijdschaal (overschrijding van het framebudget), een hoge Renderer-indicator (duidt op offscreen rendering) en lage FPS. Voor productiemonitoring verzamelt MetricKit rapporten met de MXAnimatoryMetric, die gemiddelde FPS, P50 en P95-frametijd omvat.

Native Jank-diagnose in iOS omvat CADisplayLink met controle van timestamp en targetTimestamp. Als de huidige timestamp aanzienlijk achterloopt op targetTimestamp, zijn een of meer frames overgeslagen. Apple raadt ook aan om os_signpost te gebruiken voor aangepaste profilering: plaats een signpost-interval aan het begin en einde van de framerendering en controleer in Instruments welke intervallen de 16.6 ms overschrijden. In SwiftUI wordt voor Jank-diagnose UIView.invalidateIntrinsicContentSize gebruikt — frequent aanroepen van deze methode duidt op een instabiele Layout.

CADisplayLink voor Jank-detectie

Swift-code detecteert overgeslagen frames via CADisplayLink. Als het verschil tussen timestamp en targetTimestamp meer dan 16.6 ms bedraagt — wordt Jank geregistreerd.

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
        }
    }
}

Jank-profileringstools

Voor Jank-profilering worden zowel ingebouwde OS-tools als SDK's van derden gebruikt. In Android is de belangrijkste tool Perfetto (verving Systrace). Perfetto maakt het mogelijk traces van maximaal 30 seconden op te nemen en te analyseren via de webinterface ui.perfetto.dev. Het toont de exacte tijdlijn met de activiteit van Choreographer, rendering-threads (RenderThread) en GPU. Voor gedetailleerde analyse van GPU-problemen wordt AGI (Android GPU Inspector) gebruikt, dat niet alleen de frametijd toont, maar ook de belasting van specifieke GPU-blokken — shaders, rasterizer, textuurblok.

In iOS is het equivalent Instruments met de sjablonen Core Animation, Metal System Trace en GPU Driver. Core Animation toont FPS en frametijd, Metal System Trace — GPU-activiteit tot op elke draw call. Voor profilering op echte apparaten onder belasting worden Firebase Performance (verzamelt Screen Rendering-metrics) en Sentry (vangt stack trace bij Jank) gebruikt. De nieuwe Android 15 Performance Hint API stelt de ontwikkelaar in staat om het systeem aan te geven welke frames belangrijk zijn en om waarschuwingen van het systeem te ontvangen bij naderende Jank.

FrameMetricsAggregator in productie

Kotlin-code gebruikt FrameMetricsAggregator voor het verzamelen van framestatistieken per sessie. Na het stoppen van de aggregator wordt het aantal overgeslagen frames weergegeven.

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}%")
    }
}

Methoden om framestotteringen te verhelpen

Het verhelpen van Jank vereist een combinatie van methoden afhankelijk van het type. Voor Layout Jank: diepe hiërarchieën vervangen door ConstraintLayout/Compose/SwiftUI, merge-tags gebruiken, requestLayout in animaties vermijden. Voor Draw Jank: Debug GPU Overdraw gebruiken om 4x+ overdraw te vinden, zware drawables vervangen door vector (VectorDrawable/PDF), voorzichtig met hardware layers — ze versnellen rendering maar verbruiken meer GPU-geheugen. Voor Thread Jank: alle I/O-bewerkingen, databasewerk en Bitmap-decodering verplaatsen naar achtergrondthreads, Kotlin Coroutines met de juiste Dispatcher of RxJava met Schedulers.io() gebruiken.

Voor GC Jank: allocaties in onDraw() en getView() minimaliseren, objectpools (ObjectPool) gebruiken, for-each vervangen door geïndexeerde for, voorzichtig met immutable data class in Kotlin met copy() — copy creëert een nieuw object. Voor IPC Jank: ContentProvider lui initialiseren via App Startup, Binder-aanroepen verplaatsen naar een achtergrondthread. Voor Rendering Jank: textuurgrootte verkleinen tot de maximale schermresolutie, ASTC- of ETC2-compressie gebruiken, onnodige shader compilation vermijden (shaders vooraf compileren). Een complete oplossing — regelmatig Perfetto/Instruments-profilering in CI en het volgen van Jank-regressies.

Anti-Jank-patroon: Async Layout

Kotlin-code demonstreert asynchroon laden van gegevens op het scherm na reportFullyDrawn, zodat zwaar werk het eerste frame niet blokkeert. De callback wordt aangeroepen nadat de gebruiker de interface ziet.

kotlin
class JankSafeLoader {

    suspend fun loadAfterFirstFrame(
        activity: Activity
    ) {
        // garanderen dat het eerste frame al is gerenderd
        if (Build.VERSION.SDK_INT >= 29) {
            activity.reportFullyDrawn()
        }

        // zware belading — na het eerste frame
        withContext(Dispatchers.IO) {
            val data = fetchHeavyData()
            withContext(Dispatchers.Main) {
                updateUI(data)
            }
        }
    }
}

Veelgestelde vragen

Wat is Jank in mobiele apps?

Jank — zijn overgeslagen renderingframes die zich manifesteren als merkbare haperingen of schokken in de animatie. Het ontstaat wanneer de voorbereidingstijd van een frame het tijdbudget overschrijdt (16.6 ms voor 60 FPS).

Wat zijn de belangrijkste oorzaken van Jank?

Layout Jank (frequente requestLayout), Draw Jank (overdraw), Thread Jank (blokkering main thread), GC Jank (garbage collection), IPC Jank (Binder-aanroepen) en Rendering Jank (zware shaders).

Hoe diagnoseer ik Jank in Android?

Gebruik Perfetto voor systeemtraces, GPU Profiling voor analyse van framefasen en FrameMetricsAggregator voor productiemonitoring. In Android Studio — CPU Profiler met Deep Java Trace.

Hoe meet ik Jank in iOS?

Via Instruments met de Core Animation- of Metal System Trace-sjabloon. Voor productie — MetricKit met MXAnimatoryMetric. Programmatisch — CADisplayLink met controle van het verschil tussen timestamp en targetTimestamp.

Welk percentage Jank wordt als kritiek beschouwd?

Volgens Google leidt een Jank-indicator van meer dan 3% scrollsessies (3 van de 100 scrolls bevatten een hapering) tot een toename van negatieve recensies met 22%. Streefindicator — minder dan 0.5% scrollsessies.

Samenvatting

  • Jank — overgeslagen frames die zichtbare animatiehaperingen in mobiele apps veroorzaken.
  • Hoofdoorzaken: Layout Jank, Draw Jank, Thread Jank, GC Jank, IPC Jank en Rendering Jank.
  • Jank-diagnose in Android — via Perfetto, GPU Profiling en FrameMetricsAggregator.
  • Jank-diagnose in iOS — via Instruments, CADisplayLink en MetricKit.
  • Het verhelpen van Jank vereist een combinatie: platte hiërarchieën, achtergrondthreads, minimale allocaties, caching.
  • Streefindicator Jank — minder dan 0.5% scrollsessies met haperingen.
  • Regelmatige profilering in CI voorkomt performanceregressies voordat ze in productie komen.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook