Lag in een mobiele app is een merkbare vertraging tussen de actie van de gebruiker en de reactie van de interface, die ontstaat door overbelasting van de hoofdthread, geheugenlekken of niet-optimale invoer-uitvoeroperaties. In tegenstelling tot bugs die verband houden met logische fouten, is lag een prestatieprobleem: de app werkt correct maar langzaam. Volgens AppDynamics Mobile App Performance Report 2024 verwijdert 62% van de gebruikers een app als deze langer dan 3 seconden hapert. Diagnose van lags vereist profilering van CPU, geheugen en netwerk met Android Studio Profiler en Xcode Instruments.
Belangrijkste punten
Lag (van het Engels lag) in een mobiele app is een subjectief voelbare vertraging tussen de actie van de gebruiker (aanraking, swipe, tekstinvoer) en de reactie van de interface. Technisch wordt lag gemeten als de tijd tussen de invoergebeurtenis en het volledig renderen van het frame: comfortabele drempel — tot 100 ms, merkbaar — vanaf 200 ms, kritisch — meer dan 500 ms.
In de gebruikersterminologie worden „lagnet” en „traag” vaak als synoniemen gebruikt, maar technisch is lag een vaste vertraging (bijv. 300 ms bij elke klik), terwijl „traag” een onregelmatige vertraging is: de app werkt soms vloeiend, soms bevriest hij een seconde. Een bug heeft, in tegenstelling tot lag, niet te maken met snelheid maar met de correctheid van de weergave.
Google Play en App Store houden rekening met prestatie-indicatoren bij het rangschikken van apps. ANR-rate, jank-frequentie en opstarttijd beïnvloeden de zichtbaarheid in zoekopdrachten en de conversie van installaties. Een app met constante lags verliest tot 40% van de gebruikers na de eerste lancering.
Lags ontstaan wanneer de hoofd-UI-thread frames niet kan verwerken met een snelheid van 60 FPS (16.6 ms per frame) of 120 FPS (8.3 ms). Laten we de belangrijkste bronnen van vertraging bekijken.
Elke synchrone bewerking in de UI-thread — lezen uit SharedPreferences, werken met de database via Room zonder suspend, decoderen van een afbeelding naar Bitmap — blokkeert het renderen van het frame. Op Android leidt dit tot overgeslagen frames (jank), op iOS tot vertraging van Core Animation-rendering.
Wanneer de Garbage Collector op Android of ARC op iOS geheugen vrijmaakt, worden alle threads onderbroken. Frequente GC-pauzes ontstaan bij het maken van veel tijdelijke objecten — bijvoorbeeld bij elke aanroep van een lijstadapter wordt een nieuwe ViewHolder-instantie gemaakt. Dit uit zich als schokkerig scrollen.
Geneste ConstraintLayout, meerdere LinearLayout, overlappende Views — elke nesting verhoogt de tijd voor measure en layout pass. Xcode geeft aan dat een diepe laaghiërarchie (meer dan 10 niveaus) een FPS-daling van 20-30% veroorzaakt.
Voor het identificeren van oorzaken van lags worden profilers in de IDE en systeembewakingstools gebruikt. Elk instrument lost zijn eigen taak op.
CPU Profiler laat zien welke methoden processortijd in beslag nemen en in welke threads ze worden uitgevoerd. Als een methode met zware berekeningen in de main thread wordt uitgevoerd — is dat de kern van het probleem. Het opnemen van een trace met ingeschakelde sample Java Method maakt het mogelijk om op elk moment de call-stack te zien en „hete punten” te vinden.
Het analoge instrument voor iOS — Time Profiler — verzamelt elke milliseconde stack-samples en laat zien welk percentage CPU-tijd elke methode in beslag neemt. De combinatie met de vlag Main Thread Only filtert alleen bewerkingen op de hoofdthread, wat direct de bronnen van lags aangeeft.
Trage netwerkverzoeken geven de indruk van lags, zelfs als de UI-thread niet is geblokkeerd. Network Profiler in Android Studio en Network Link Conditioner in Xcode maken het mogelijk om een trage verbinding te simuleren en te zien hoe de app zich gedraagt in reële omstandigheden. Chunked-antwoorden zonder voortgang en grote JSON-ladingen zijn typische bronnen van schijnbare lags.
Voorbeeld van profilering van een netwerkverzoek met OkHttp met tijdsmeting:
class TimingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val start = System.nanoTime()
val response = chain.proceed(chain.request())
val duration = (System.nanoTime() - start) / 1_000_000
Log.d("Timing", "Verzoek duurde $duration ms")
return response
}
}
Het verhelpen van lags vereist systematisch werk: van optimalisatie van één methode tot architectuurwijzigingen. Laten we de meest effectieve technieken bekijken.
Kotlin Coroutines met dispatcher Dispatchers.IO voor netwerkverzoeken en Dispatchers.Default voor berekeningen garanderen dat de hoofdthread vrij blijft voor de UI. Op iOS is Grand Central Dispatch met queue .global(qos: .userInitiated) voor achtergrondtaken en .main voor UI-updates de standaardaanpak. Vermijd sync-bewerkingen tussen wachtrijen.
RecyclerView op Android en UICollectionView op iOS vereisen correcte configuratie: ViewHolder met minimale objectcreatie in onBindViewHolder, DiffUtil voor het berekenen van wijzigingen, prefetching voor het vooraf laden van gegevens. Gebruik op iOS diffable data source voor geanimeerde updates zonder handmatig beheer.
Het laden van dezelfde afbeelding bij elke scrollbeweging is een gegarandeerde lag. Coil (Android) en Kingfisher (iOS) cachen afbeeldingen in het geheugen en op schijf, wat zorgt voor onmiddellijke weergave bij een herhaald verzoek. Gebruik voor gegevens Room met een cachelaag op basis van Flow of Combine.
Voorbeeld van het configureren van afbeeldingscaching met Coil op Android:
val imageLoader = ImageLoader(context) {
memoryCachePolicy(CachePolicy.ENABLED)
diskCachePolicy(CachePolicy.ENABLED)
crossfade(true)
size(512, 512)
}
// Laden met ingeschakelde automatische caching
imageView.load("https://example.com/image.jpg") {
placeholder(R.drawable.placeholder)
error(R.drawable.error)
}
Lags voorkomen is goedkoper dan ze in productie te repareren. Preventieve maatregelen worden ingebouwd in het ontwikkelingsproces op het niveau van tools en architectuur.
StrictMode — een ingebouwde Android-tool die toevallige invoer-uitvoeroperaties en netwerkaanroepen op de hoofdthread detecteert in de ontwikkelingsfase. Schakel het in in Application.onCreate met het beleid penaltyDeath voor kritieke overtredingen. Dit is de enige manier om te garanderen dat de ontwikkelaar het probleem ziet vóór de commit.
De analoog voor iOS — Main Thread Checker in Xcode, onderdeel van Runtime Sanitization. Het controleert automatisch of alle UIKit- en AppKit-aanroepen vanuit de hoofdthread worden uitgevoerd. Schakel het in in het Debug-buildschema en streef naar nul waarschuwingen in CI.
Voeg in de CI-pijplijn het uitvoeren van Macrobenchmark (Android) en XCTMetrics (iOS) toe voor het meten van opstarttijd, scroll-FPS en geheugengebruik. Stel drempels in: als een nieuwe commit de opstarttijd met meer dan 5% verhoogt — faalt de build.
Veelgestelde vragen
Lag is een subjectief gevoel van vertraging dat zelfs bij hoge FPS kan optreden als de vertraging wordt veroorzaakt door de verwerkingstijd van invoer, niet door rendering. Lage FPS (minder dan 30 frames/s) is een van de oorzaken van lags, maar niet de enige.
Gebruik Frame Timing API op Android (Choreographer) en CADisplayLink op iOS om de tijd tussen frames te meten. Google Play Vitals toont de jank-rate in reële omstandigheden. Voor nauwkeurige metingen gebruik je Macrobenchmark met scrollscenario's.
Oudere apparaten hebben minder CPU-kernen, minder RAM en langzamer geheugen. Een bewerking die op een vlaggenschip 5 ms duurt, kan op een budgetapparaat 50 ms duren. Test de prestaties op low-end apparaten en stel Baseline Profiles in voor AOT-compilatie.
Ja, dit is een van de meest effectieve methoden. Afbeeldingen met hoge resolutie nemen veel geheugen en CPU-tijd in beslag voor decodering. Gebruik downscale tot View-formaat, WebP-formaten (Android) en HEIC (iOS), en caching via Coil of Kingfisher.
SwiftUI optimaliseert updates automatisch via diffing, wat het risico op lags bij gegevenswijzigingen vermindert. Echter, complexe hiërarchieën en frequente herbouw van body kunnen FPS-daling veroorzaken. UIKit biedt meer controle over prestaties, maar vereist handmatige optimalisatie.
Samenvatting
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.
Lees ook