FPS (Frames Per Second) — is een metriek die aangeeft hoeveel individuele frames het grafische systeem in één seconde weergeeft. In mobiele ontwikkeling is FPS een standaard prestatie-indicator van de UI: hoe hoger de FPS, hoe vloeiender de animaties en hoe responsiever de interface. Volgens gegevens van Google Android Performance, 2025 is de doelwaarde van FPS voor mobiele apps 60 frames per seconde — dit is de drempel waarbij het menselijk oog beweging als continu en vloeiend waarneemt.
Belangrijkste punten
FPS (Frames Per Second) — is een meeteenheid voor de framerate die wordt gebruikt in computergraphics, video en mobiele interfaces. Elk frame is een statisch beeld dat gedurende een korte tijd op het scherm wordt weergegeven. Bij snelle opeenvolging van frames neemt de hersenen ze waar als continue beweging — dit effect wordt persistentie van het gezichtsvermogen genoemd. Voor mobiele apps is FPS een kritieke metriek, omdat elk gemist frame (drop) een vloeiende animatie verandert in een merkbare hapering. De app moet elk frame strikt binnen het tijdsbudget kunnen renderen: 16.6 ms voor 60 FPS, 11.1 ms voor 90 FPS, 8.3 ms voor 120 FPS.
FPS wordt niet alleen gemeten voor de UI, maar ook voor games, video en camera. In games hangt FPS af van de complexiteit van de scène, de kwaliteit van texturen en de kracht van de GPU. In video is FPS vast (24, 30, 60 fps) en wordt bepaald door de inhoud. In mobiele apps hangt FPS af van de efficiëntie van de UI-code: de complexiteit van de Layout, het aantal Views, de frequentie van hertekenen en het werk van de GC (Garbage Collection). Volgens Apple WWDC 2022 kan de gemiddelde FPS in een app met 10–15% dalen door inefficiënte collectie-updates (reloadData in plaats van insert/delete/dequeueReusableCell). FPS-meting in real-time is een standaardpraktijk voor QA-ingenieurs en ontwikkelaars die aan prestaties werken.
De berekening van FPS in een mobiele app is gebaseerd op het meten van de tijd tussen opeenvolgende frames. De eenvoudigste formule: FPS = 1000 / deltaTimeMs, waarbij deltaTimeMs het interval is tussen het einde van het vorige frame en het einde van het huidige frame. Als het huidige frame in 20 ms is gerenderd, is FPS = 1000 / 20 = 50. In de praktijk is FPS echter zelden stabiel, zelfs niet binnen één seconde: een typisch profiel bevat frames van 12–16 ms, afgewisseld met overgeslagen (jank) of langzame frames (40–60 ms). Daarom wordt FPS gemeten als een voortschrijdend gemiddelde over 1–5 seconden of als percentielen van de frametijdverdeling.
In Android wordt FPS berekend via Choreographer, die een callback ontvangt van VSync (de synchronisatiepuls van het scherm). Elke callback komt overeen met één frame. Als de callback niet komt — is het frame overgeslagen. Choreographer maakt het mogelijk om het exacte aantal frames per seconde en het aantal overgeslagen (skipped frames) te meten. In iOS werkt CADisplayLink op dezelfde manier — het wordt elke keer aangeroepen wanneer het scherm klaar is om een nieuw frame te renderen. De eigenschap timestamp bevat de exacte tijd van het laatste frame, en targetTimestamp — de verwachte tijd van het volgende. Het verschil ertussen is het tijdsbudget voor het huidige frame.
Code in Swift demonstreert eenvoudige FPS-monitoring via CADisplayLink. De teller frameCount wordt bij elke aanroep verhoogd en één keer per seconde wordt de werkelijke FPS berekend.
class FpsCounter {
private var displayLink: CADisplayLink?
private var frameCount = 0
private var lastTime = TimeInterval(0)
func start() {
displayLink = CADisplayLink(
target: self,
selector: #selector(countFrame)
)
displayLink?.add(to: .current,
forMode: .common)
}
@objc
private func countFrame() {
frameCount += 1
let now = Date().timeIntervalSince1970
if now - lastTime >= 1.0 {
print("FPS: \(frameCount)")
frameCount = 0
lastTime = now
}
}
}
De standaard 60 FPS (60 Hz) is om verschillende redenen in de industrie verankerd. De eerste — fysiologisch: het menselijk oog onderscheidt geen afzonderlijke frames bij een frequentie boven 50–60 Hz en neemt ze waar als vloeiende beweging. Deze drempel wordt Critical Flicker Fusion (CFF) genoemd. De tweede — historisch: de eerste kathodestraalbuizen (CRT) werkten op 60 Hz in de VS (NTSC) en 50 Hz in Europa (PAL). Moderne LCD-schermen hebben deze frequentie geërfd. De derde — technisch: voor UI-animaties zorgt 60 FPS voor een submilliseconde reactietijd op aanraking, wat cruciaal is voor tekstinvoer, scrollen en slepen.
Voor mobiele ontwikkelaars is 60 FPS niet alleen een aanbeveling, maar een strikt budget van 16.6 ms per frame. Dit budget wordt verdeeld over alle renderingsfasen: Input (1–2 ms), Animation (2–3 ms), Layout (3–5 ms), Draw (3–5 ms) en Swap (1–2 ms). Als een fase zijn subbudget overschrijdt, past het frame mogelijk niet in 16.6 ms. Google Android Performance raadt aan om 12–14 ms te besteden aan de voorbereiding van het frame, met 2–4 ms reserve voor systeemonderbrekingen (GC, achtergrondthreads). Volgens Firebase Performance krijgen apps met een gemiddelde FPS onder 52 en P99 FPS onder 30 35% meer klachten over prestaties in Google Play-recensies.
FPS en Frame Time (frametijd) — zijn twee kanten van dezelfde metriek en het is belangrijk om ze niet te verwarren. FPS is snelheid, Frame Time is vertraging. Bij 60 FPS duurt elk frame 16.6 ms. Bij 30 FPS — 33.3 ms. Maar FPS is een niet-lineaire metriek: een daling van 60 naar 30 FPS betekent dat de frametijd is verdubbeld, en een daling van 30 naar 20 — 1,5 keer. Daarom tonen profilers niet FPS, maar Frame Time — dit maakt het mogelijk om probleemframes te zien, niet de gemiddelde frequentie. Een gemiddelde van 55 FPS kan bijvoorbeeld verbergen dat 5% van de frames een Frame Time van 50–100 ms heeft — deze frames veroorzaken Jank, maar hebben geen grote invloed op de gemiddelde FPS.
Bij prestatieanalyse wordt aanbevolen om niet naar de gemiddelde FPS te kijken, maar naar het histogram van Frame Time. In Android Studio Profiler en iOS Instruments wordt Frame Time weergegeven als een schaal, waarbij de groene zone — tot 16.6 ms (60 FPS), geel — 16.6–33.3 ms (30–60 FPS), rood — meer dan 33.3 ms (minder dan 30 FPS). Elke rode kolom is een merkbare vertraging voor de gebruiker. Praktische regel: P95 Frame Time (95% van de frames past in X ms) — is een betrouwbaardere metriek dan de gemiddelde FPS. Als P95 Frame Time hoger is dan 32 ms (30 FPS), wordt de app als traag ervaren, zelfs bij een gemiddelde FPS van 50.
Functie in Kotlin voor het converteren van een array met frametijden naar FPS met percentielen. Geeft niet alleen de gemiddelde FPS terug, maar ook P50, P90 en P99 voor gedetailleerde analyse.
data class FpsReport(
val average: Float,
val p50: Float,
val p90: Float,
val p99: Float
)
fun List<Long>.toFpsReport(): FpsReport {
val fpsValues = this.map { ms ->
if (ms > 0) 1000f / ms else 0f
}.sorted()
return FpsReport(
average = fpsValues.average().toFloat(),
p50 = fpsValues[fpsValues.size / 2],
p90 = fpsValues[(fpsValues.size * 90 / 100)],
p99 = fpsValues[(fpsValues.size * 99 / 100)]
)
}
Moderne mobiele apparaten met schermen van 90, 120 en 144 Hz stellen nieuwe eisen aan FPS. Als een app 60 FPS levert op een 120 Hz-scherm, ziet de gebruiker micro-haperingen, omdat elke tweede verversingscyclus van het scherm hetzelfde frame krijgt. Om 120 FPS te behouden, wordt het budget per frame verminderd van 16.6 naar 8.3 ms — dit vereist twee keer zo efficiënte renderingscode. Volgens Android-ontwikkelaars (Google I/O 2023) is het voor stabiele 120 FPS noodzakelijk: allocaties in de Draw-cyclus vermijden, het aantal Views in de hiërarchie minimaliseren (minder dan 80), zware drawables vervangen door VectorDrawable en surfaceView gebruiken voor complexe graphics.
In iOS is de situatie vergelijkbaar: iPhone Pro met ProMotion (120 Hz) vereist twee keer zoveel frames, maar de tijd per frame is half zo kort. Apple merkt op dat niet alle animaties op 120 FPS hoeven te werken — Core Animation verlaagt automatisch de frequentie voor stilstaande of langzaam veranderende elementen. Scrollen, gebarenanimaties en overgangen moeten echter 120 FPS leveren voor een "zijdeachtig" gevoel. De belangrijkste problemen bij de overgang van 60 naar 120 FPS: hoger energieverbruik (25–40% voor de GPU), opwarming van het apparaat en throttling — wanneer de frequentie daalt door oververhitting. Het wordt aanbevolen om een fallback-mechanisme te implementeren: als Frame Time consistent boven 8.3 ms ligt, verlaag dan programmatisch de doelfrequentie naar 60 FPS, in plaats van te wachten op systeem-throttling.
Code in Java voor Android bepaalt of het apparaat 120 FPS kan ondersteunen en schakelt de renderingsmodus om. Gebruikt Display.getMode om de ondersteunde frequenties te bepalen.
class FpsModeSwitcher {
static boolean canDo120Fps(Activity activity) {
Display display = activity.getWindowManager()
.getDefaultDisplay();
for (Display.Mode mode : display.getSupportedModes()) {
if (mode.getRefreshRate() >= 120f) {
return true;
}
}
return false;
}
}
Optimalisatie van FPS vereist een systematische aanpak, beginnend met profilering en eindigend met refactoring van probleemgebieden. De eerste fase — de huidige FPS meten met een profiler (. De tweede fase — frames vinden die het budget overschrijden. Voor Android kan dit via GPU Profiling of Perfetto. Voor iOS — Instruments met de sjabloon Core Animation. De derde fase — oorzaken wegnemen: overdraw verminderen, de diepte van View-nesting verminderen, de Layout-fase vervangen door ConstraintLayout, ViewHolder Recycling toevoegen, zware berekeningen naar een achtergrondthread verplaatsen.
Specifieke FPS-optimalisaties omvatten: Frame Pacing — een mechanisme dat de tijd gelijkmatig over frames verdeelt om "pieken" van snelle en langzame frames te voorkomen. In Android maakt Choreographer.FrameCallback met een vast interval Frame Pacing mogelijk. In iOS doet CADisplayLink.preferredFrameRateRange hetzelfde. Het tweede mechanisme — Triple Buffering: het systeem gebruikt drie buffers in plaats van twee, waardoor de GPU kan beginnen met het tekenen van het volgende frame zonder te wachten op het vrijkomen van de vorige. Android schakelt automatisch Triple Buffering in wanneer nodig, maar in iOS kan de ontwikkelaar dit expliciet aanvragen via CAMetalLayer. De derde — Texture Caching: het cachen van bitmaps in het GPU-geheugen om ze niet opnieuw te laden bij elk frame.
Voorbeeld in Kotlin demonstreert de implementatie van Frame Pacing met een vast interval van 16.6 ms. Alle callbacks komen met een uniform interval, zelfs als het systeem vertraging heeft.
class PacedFrameRenderer {
private val targetDelta = 16_666_666L // 16.6 ms (60 FPS)
private var lastFrameTime = 0L
private val frameCallback =
Choreographer.FrameCallback { frameTimeNanos ->
val delta = frameTimeNanos - lastFrameTime
if (delta >= targetDelta) {
onFrame(delta)
lastFrameTime = frameTimeNanos
}
Choreographer.getInstance()
.postFrameCallback(this)
}
private fun onFrame(delta: Long) {
// frame weergeven
}
}
Veelgestelde vragen
60 FPS — comfortabel niveau voor mobiele apps. Het verschil tussen 60 en 120 FPS is alleen merkbaar op schermen met een hoge verversingssnelheid bij snelle animaties (scrollen, slepen). Onder 30 FPS — ongemakkelijk.
FPS = 1000 / FrameTime (ms). Als Frame Time = 16.6 ms, FPS = 60. Als Frame Time = 33.3 ms, FPS = 30. Het wordt aanbevolen om Frame Time te monitoren in plaats van FPS, omdat het probleemframes laat zien.
Tijdens het scrollen roept het systeem Layout en Draw aan voor elk nieuw element van de lijst. Als Views complex zijn, Layout niet wordt gecached of zware drawables worden gebruikt — stijgt de Frame Time en daalt de FPS. Oplossing — ViewHolder recycling en platte hiërarchie.
Gebruik Instruments met de Core Animation-sjabloon (toont FPS in real-time). Voor programmatische meting — CADisplayLink met het tellen van frames per seconde. Voor productie — MetricKit met de metriek MXAnimatoryMetric.
Triple Buffering gebruikt drie buffers in plaats van twee, waardoor de GPU kan beginnen met het renderen van het volgende frame voordat de VSync van het huidige frame is voltooid. Dit egaliseert piekbelastingen en verhoogt de stabiliteit van FPS, maar voegt 1 frame vertraging toe.
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