Frame Rate — is het aantal frames dat het grafische systeem in één seconde weergeeft. In mobiele apps bepaalt de framesnelheid direct de vloeiendheid van animaties, scrollen en overgangen tussen schermen. Volgens gegevens van Android Developers, 2025 is de beoogde Frame Rate 60 fps voor standaard displays en 120 fps voor apparaten met een hoge verversingssnelheid. Afwijking van de streefwaarde leidt tot visuele haperingen en een verslechterde gebruikerservaring.
Belangrijkste punten
Frame Rate (framesnelheid) — is een metriek gemeten in frames per seconde (fps) die aangeeft hoe vaak per seconde een app het beeld op het scherm ververst. Het menselijk oog neemt beweging als vloeiend waar vanaf 24 fps (film), maar voor interactieve UI is minimaal 60 fps nodig zodat aanrakingen en animaties direct aanvoelen. Elk frame is een volledige cyclus: verwerking van gebruikersinvoer, berekening van de Layout, rendering van de View-hiërarchie en weergave op het scherm. Als een van de fasen het toegewezen tijdbudget overschrijdt (16.6 ms bij 60 fps), wordt het frame overgeslagen en ziet de gebruiker een hapering.
Het is belangrijk om de Frame Rate van de app te onderscheiden van de verversingssnelheid van het display (Refresh Rate). De verversingssnelheid is een kenmerk van het scherm: hoe vaak per seconde het display het beeld fysiek ververst (60, 90, 120 of 144 Hz). Frame Rate — is hoeveel frames per seconde de app kan renderen. Als een app 60 fps produceert op een 120 Hz display, wordt elk tweede frame gedupliceerd — het beeld blijft vloeiend, maar niet zo responsief als het zou kunnen zijn. Volgens Google I/O 2023 kunnen moderne vlaggenschepen 120 fps behouden in eenvoudige UI-scenario’s, maar bij zware belasting (games, complexe lijsten) daalt de snelheid naar 40–60 fps.
Het renderen van een frame in een mobiele app doorloopt een pijplijn van verschillende fasen. In Android omvat de pijplijn: verwerking van invoer (Input), animatie (Animation), meting en plaatsing (Layout), tekenen (Draw), synchronisatie met GPU en weergave op het scherm (Swap). Elke fase wordt uitgevoerd op de CPU of GPU, en de totale tijd van alle fasen mag het framebudget niet overschrijden. Voor 60 fps is het budget 16.6 ms, voor 120 fps — 8.3 ms. Choreographer (Android) en CADisplayLink (iOS) synchroniseren de rendering met de verticale verversing van het display (VSync), zodat een frame alleen wordt weergegeven op het moment van schermverversing, waardoor tearing (scheuren van het beeld) wordt voorkomen.
In iOS is de pijplijn vergelijkbaar: Run Loop verwerkt gebeurtenissen, Core Animation berekent lagen, Render Server (een apart proces) rendert en stuurt het frame naar de GPU. Het verschil in iOS — het aparte Render Server-proces dat de rendering isoleert van de hoofdapp. Als de app de main thread blokkeert, kan Render Server nog steeds het laatste bekende frame weergeven, maar animaties stoppen. Als Render Server zelf niet op tijd is — staat de GPU stil en daalt de Frame Rate. Volgens Apple WWDC 2022 zijn de meest voorkomende oorzaken van lage Frame Rate in iOS overmatige nesting van CALayer, zware shadowPath en offscreen rendering.
Code in Kotlin abonneert zich op Choreographer.FrameCallback en logt de werkelijke tijd tussen frames. Als het interval groter is dan 16.6 ms — wordt een overgeslagen frame geregistreerd.
class FrameRateMonitor {
private var lastFrameTime = 0L
private val frameCallback =
Choreographer.FrameCallback { frameTimeNanos ->
if (lastFrameTime != 0L) {
val deltaMs = (frameTimeNanos - lastFrameTime) / 1_000_000f
if (deltaMs > 16.6f) {
Log.w("FrameRate",
"Skipped frame: $deltaMs ms")
}
}
lastFrameTime = frameTimeNanos
Choreographer.getInstance()
.postFrameCallback(this)
}
fun start() {
Choreographer.getInstance()
.postFrameCallback(frameCallback)
}
}
Refresh Rate (verversingssnelheid) — is een hardwarekenmerk van het display dat bepaalt hoe vaak per seconde het scherm het beeld fysiek hertekent. Standaard displays hebben 60 Hz, moderne vlaggenschepen — 90, 120 of 144 Hz. De Frame Rate van de app kan lager, gelijk of hoger zijn dan de verversingssnelheid (in het laatste geval worden overtollige frames weggegooid). Het ideale scenario — Frame Rate komt overeen met Refresh Rate: elke hardwarecyclus krijgt een nieuw frame van de app en beweging is maximaal vloeiend. Als Frame Rate lager is, herhaalt het display het laatste frame, wat wordt waargenomen als micro-haperingen (stutter).
Android en iOS ondersteunen het dynamisch schakelen van de verversingssnelheid. Android 12+ gebruikt Smart Refresh Rate: bij scrollen verhoogt het systeem de snelheid naar 120 Hz, bij statische inhoud verlaagt het naar 60 Hz om batterij te sparen. iOS ProMotion (iPhone 13 Pro en nieuwer) werkt vergelijkbaar — de snelheid varieert van 10 tot 120 Hz afhankelijk van de inhoud. De ontwikkelaar moet controleren of het apparaat hoge verversing ondersteunt en het tijdbudget per frame aanpassen. Als de app geen frame kan renderen in 8.3 ms (voor 120 Hz), is het beter om gedwongen op 60 Hz te werken — dit zorgt voor een stabiele Frame Rate zonder overgeslagen frames.
| Type display | Refresh Rate | Budget per frame | Apparaten |
|---|---|---|---|
| Standaard | 60 Hz | 16.6 ms | Meeste Android/iOS |
| Hoog | 90 Hz | 11.1 ms | OnePlus, Pixel 6+ |
| Flagship | 120 Hz | 8.3 ms | iPhone Pro, Galaxy S22+ |
| Gaming | 144 Hz | 6.9 ms | ROG Phone, Nubia RedMagic |
Voor het meten van Frame Rate in mobiele apps zijn zowel ingebouwde tools van de platforms als externe profilers beschikbaar. In Android is de belangrijkste tool GPU Profiling (Developer Options → Profile GPU Rendering) die de tijdschaal van elk frame toont met uitsplitsing per fase (Draw, Prepare, Process, Execute). Een gedetailleerdere analyse biedt Android Studio Profiler — hij registreert een volledig renderprofiel met vermelding van specifieke Views die hertekenen veroorzaken. In iOS wordt Instruments met de Core Animation-sjabloon gebruikt — het toont FPS, rendertijd van lagen en het aantal offscreen-renders.
Voor productiemonitoring van Frame Rate wordt Firebase Performance (Android) gebruikt — het verzamelt Frame Rate op de achtergrond en aggregeert per apparaat, OS-versie en sessie. In iOS biedt MetricKit vergelijkbare gegevens via MXAnimatoryMetric. Voor games en Flutter-apps worden FrameTimingCallback (Flutter) en Unity Profiler gebruikt. Het is belangrijk om niet de gemiddelde Frame Rate te meten, maar percentielen: P50, P90 en P99. Een app kan een gemiddelde van 55 fps tonen, maar P99 = 30 fps hebben — dit betekent dat 1% van de tijd gebruikers sterke haperingen zien en dit is voldoende voor negatieve recensies.
Een voorbeeld in Dart laat zien hoe je je abonneert op FrameTimingCallback in Flutter en het aantal overgeslagen frames logt. De callback wordt geactiveerd na elk voltooid frame.
import 'package:flutter/scheduler.dart';
class FrameRateLogger {
int totalFrames = 0;
int missedFrames = 0;
void start() {
SchedulerBinding.instance
.addTimingsCallback(_onReportTimings);
}
void _onReportTimings(List<FrameTiming> timings) {
for (final timing in timings) {
totalFrames++;
if (timing.totalSpan()
> Duration(milliseconds: 16)) {
missedFrames++;
}
}
debugPrint("FPS: \${totalFrames - missedFrames}");
}
}
Optimalisatie van Frame Rate begint met het identificeren van knelpunten in de renderpijplijn. In de Layout-fase zijn de belangrijkste problemen overmatige nesting van de View-hiërarchie, gebruik van relatieve Layouts (RelativeLayout met veel regels) en frequente aanroepen van requestLayout. Oplossing — gebruik van ConstraintLayout of een platte hiërarchie, vermijd nesting van meer dan 5–6 niveaus. In de Draw-fase — overtekenen (overdraw): wanneer een pixel meerdere keren per frame wordt getekend. Bijvoorbeeld een witte achtergrond van Activity onder een semi-transparante fragment, waaronder nog een laag — elke pixel wordt drie keer getekend. De tool Debug GPU Overdraw toont probleemzones met kleurindicatie. Het wordt aanbevolen om overdraw op 2x of lager te houden.
In iOS zijn de belangrijkste problemen zware cornerRadius en masksToBounds — ze veroorzaken offscreen rendering, waarbij Core Animation een tijdelijke buffer maakt, erin tekent en vervolgens het resultaat naar het scherm kopieert. Offscreen rendering is gemakkelijk te zien in Instruments Core Animation: als de Renderer-regel rood is — zijn er problemen. Oplossing — gebruik UIImageView met vooraf bijgesneden afbeeldingen in plaats van cornerRadius, vermijd groupOpacity en shouldRasterize zonder noodzaak. Voor beide platforms is het cruciaal om het aantal aanroepen van invalidate() en setNeedsDisplay() te minimaliseren — elke dergelijke aanroep start een volledige hertekeningscyclus van de weergave.
Code demonstreert het vervangen van diepe nesting van RelativeLayout door een platte structuur met ConstraintLayout. Het verminderen van het nestniveau van 4 naar 1 verkort de Layout-tijd met 30–50%.
// Voorbeeld: platte structuur via ConstraintLayout
class OptimizedView(context: Context) :
ConstraintLayout(context) {
private val binding =
ItemProfileBinding.inflate(
LayoutInflater.from(context)
)
fun bind(user: User) {
binding.avatar.setImageURI(user.avatarUrl)
binding.nameText.text = user.name
// gegevens koppelen zonder de hele container te hertekenen
}
}
Moderne mobiele apps gebruiken steeds vaker adaptieve Frame Rate — een systeem dat de beoogde snelheid dynamisch aanpast aan het huidige scenario. Bij snel scrollen heeft de lijst 120 fps nodig voor vloeiendheid, bij een statisch scherm is 60 fps of zelfs 30 fps voor video voldoende. In Android wordt aanpassing gerealiseerd via Choreographer.setFrameInterval (API 33+) en Window.setFrameRate. De ontwikkelaar kan het systeem een voorkeurssnelheid aangeven: setPreferredRefreshRate in SurfaceView of setFrameRate in Window. iOS beheert automatisch de snelheid via ProMotion, maar de ontwikkelaar kan expliciet preferredFramesPerSecond instellen voor CADisplayLink.
Dynamische Frame Rate is vooral belangrijk voor games en apps met animaties. Volgens Google bespaart het verlagen van Frame Rate van 120 naar 60 Hz op een statisch scherm tot 30–40% GPU-energie. Om de beste balans tussen vloeiendheid en energieverbruik te bereiken, wordt aanbevolen: meet de werkelijke Frame Rate in verschillende scenarioën, stel de beoogde fps in op basis van de scène (game — 60, menu — 30, video — 24) en schakel modi via Lifecycle-aware componenten, zodat de app bij minimalisatie geen resources verspilt aan het renderen van 120 fps op de achtergrond.
Code in Swift stelt preferredFramesPerSecond in voor CADisplayLink in iOS. Bij scrollen stijgt de snelheid naar 120 Hz, bij stoppen — daalt naar 60 Hz.
class AdaptiveFrameRateManager {
private var displayLink: CADisplayLink?
func startWithHighRate() {
displayLink = CADisplayLink(
target: self,
selector: #selector(step)
)
if #available(iOS 15.0, *) {
displayLink?.preferredFrameRateRange =
CAFrameRateRange(
minimum: 60,
maximum: 120,
preferred: 120
)
}
displayLink?.add(to: .current,
forMode: .common)
}
@objc
private func step() {
// animatie-update
}
}
Veelgestelde vragen
Voor mobiele apps is de beoogde Frame Rate 60 fps (16.6 ms per frame). Voor apparaten met 120 Hz displays is 120 fps wenselijk. Waarden onder 30 fps verslechteren de gebruikerservaring aanzienlijk.
Frame Rate — hoeveel frames per seconde de app rendert. Refresh Rate — hoe vaak per seconde het display het beeld fysiek ververst. Wanneer Frame Rate lager is dan Refresh Rate, herhaalt het display het laatste frame.
Gebruik GPU Profiling in Developer Options, Android Studio Profiler of Firebase Performance. Voor programmatische meting — Choreographer.FrameCallback met berekening van het interval tussen frames.
Overdraw — het meerdere keren per frame tekenen van dezelfde pixel. Elke extra laag verhoogt de tijd van de Draw-fase en verlaagt de Frame Rate. Optimale overdraw is 2x, kritisch — 4x en hoger.
Bij statische inhoud verlaagt Dynamic Frame Rate de snelheid naar 30–60 Hz, waardoor de GPU-belasting met 30–40% afneemt. Bij scrollen stijgt de snelheid naar 90–120 Hz voor vloeiendheid.
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