Frame Rate — a képkockák száma, amelyet a grafikus rendszer egy másodperc alatt megjelenít. Mobilalkalmazásokban a képkockasebesség közvetlenül meghatározza az animációk, görgetés és képernyők közötti átmenetek simaságát. A Android Developers, 2025 adatai szerint a cél Frame Rate 60 fps a szabványos kijelzőknél és 120 fps a magas frissítési frekvenciájú eszközöknél. A célértéktől való eltérés vizuális akadozáshoz és a felhasználói élmény romlásához vezet.
Főbb pontok
Frame Rate (képkockasebesség) — egy metrika, amelyet másodpercenkénti képkockákban (fps) mérnek, és megmutatja, hogy az alkalmazás másodpercenként hányszor frissíti a képet a képernyőn. Az emberi szem 24 fps-től (mozi) érzékeli a mozgást simának, de interaktív UI-hoz minimum 60 fps szükséges, hogy az érintések és animációk azonnalinak tűnjenek. Minden képkocka egy teljes ciklus: a felhasználói bevitel feldolgozása, a Layout kiszámítása, a View hierarchia renderelése és megjelenítése a képernyőn. Ha bármelyik szakasz meghaladja a kiosztott időkeretet (16.6 ms 60 fps-nél), a képkocka kimarad, és a felhasználó akadozást lát.
Fontos megkülönböztetni az alkalmazás Frame Rate-ét a kijelző frissítési frekvenciájától (Refresh Rate). A frissítési frekvencia a képernyő jellemzője: másodpercenként hányszor frissíti fizikailag a kijelző a képet (60, 90, 120 vagy 144 Hz). A Frame Rate — hogy hány képkockát másodpercenként képes renderelni az alkalmazás. Ha az alkalmazás 120 Hz-es kijelzőn 60 fps-t produkál, minden második képkocka megkettőződik — a kép sima marad, de nem olyan reszponzív, mint lehetne. A Google I/O 2023 adatai szerint a modern zászlóshajók 120 fps-t képesek tartani egyszerű UI-forgatókönyvekben, de nehéz terhelésnél (játékok, összetett listák) a frekvencia 40–60 fps-re csökken.
A képkocka renderelése egy mobilalkalmazásban több szakaszból álló csővezetéken halad át. Androidban a csővezeték a következőket foglalja magában: bevitel feldolgozása (Input), animáció (Animation), mérés és elrendezés (Layout), rajzolás (Draw), szinkronizálás a GPU-val és megjelenítés a képernyőn (Swap). Minden szakasz CPU-n vagy GPU-n fut, és az összes szakasz teljes ideje nem haladhatja meg a képkocka költségkeretét. 60 fps-hez a keret 16.6 ms, 120 fps-hez — 8.3 ms. A Choreographer (Android) és a CADisplayLink (iOS) szinkronizálja a renderelést a kijelző függőleges frissítésével (VSync), garantálva, hogy a képkocka csak a képernyő frissítésekor jelenjen meg, elkerülve a kép szakadását (tearing).
iOS-ben a csővezeték hasonló: a Run Loop feldolgozza az eseményeket, a Core Animation kiszámítja a rétegeket, a Render Server (egy külön folyamat) renderel és elküldi a képkockát a GPU-nak. Az iOS különbsége — a külön Render Server folyamat, amely elkülöníti a renderelést a főalkalmazástól. Ha az alkalmazás blokkolja a fő szálat, a Render Server továbbra is megjelenítheti az utolsó ismert képkockát, de az animációk megállnak. Ha maga a Render Server nem tart lépést — a GPU tétlen, és a Frame Rate csökken. Az Apple WWDC 2022 adatai szerint az iOS-ben az alacsony Frame Rate leggyakoribb okai a CALayer túlzott egymásba ágyazása, a nehéz shadowPath és a képernyőn kívüli renderelés (offscreen rendering).
A Kotlin kód feliratkozik a Choreographer.FrameCallback-ra, és naplózza a képkockák közötti tényleges időt. Ha az intervallum meghaladja a 16.6 ms-ot — egy kihagyott képkocka kerül rögzítésre.
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 (frissítési frekvencia) — a kijelző hardverjellemzője, amely meghatározza, hogy a képernyő másodpercenként hányszor rajzolja újra fizikailag a képet. A szabványos kijelzők 60 Hz-esek, a modern zászlóshajók — 90, 120 vagy 144 Hz-esek. Az alkalmazás Frame Rate-e lehet alacsonyabb, egyenlő vagy magasabb a frissítési frekvenciánál (ez utóbbi esetben a többlet képkockák eldobásra kerülnek). Az ideális forgatókönyv — a Frame Rate megegyezik a Refresh Rate-tel: minden hardverciklus új képkockát kap az alkalmazástól, és a mozgás maximálisan sima. Ha a Frame Rate alacsonyabb, a kijelző megismétli az utolsó képkockát, ami mikro-akadozásként (stutter) érzékelhető.
Az Android és az iOS támogatja a frissítési frekvencia dinamikus váltását. Az Android 12+ a Smart Refresh Rate-et használja: görgetéskor a rendszer 120 Hz-re emeli a frekvenciát, statikus tartalomnál 60 Hz-re csökkenti az akkumulátor kímélése érdekében. Az iOS ProMotion (iPhone 13 Pro és újabb) hasonlóan működik — a frekvencia 10 és 120 Hz között változik a tartalomtól függően. A fejlesztőnek ellenőriznie kell, hogy az eszköz támogatja-e a magas frekvenciát, és hozzá kell igazítania a képkockánkénti időkeretet. Ha az alkalmazás nem tud képkockát renderelni 8.3 ms alatt (120 Hz-hez), jobb kényszeríteni a 60 Hz-es működést — ez stabil Frame Rate-et biztosít kihagyott képkockák nélkül.
| Kijelző típusa | Refresh Rate | Képkocka keret | Eszközök |
|---|---|---|---|
| Szabványos | 60 Hz | 16.6 ms | A legtöbb Android/iOS |
| Magas | 90 Hz | 11.1 ms | OnePlus, Pixel 6+ |
| Zászlóshajó | 120 Hz | 8.3 ms | iPhone Pro, Galaxy S22+ |
| Játék | 144 Hz | 6.9 ms | ROG Phone, Nubia RedMagic |
A Frame Rate mérésére mobilalkalmazásokban mind a platformok beépített eszközei, mind külső profilerek rendelkezésre állnak. Androidban a fő eszköz a GPU Profiling (Developer Options → Profile GPU Rendering), amely minden képkocka időskáláját mutatja szakaszokra bontva (Draw, Prepare, Process, Execute). Részletesebb elemzést nyújt az Android Studio Profiler — rögzíti a renderelés teljes profilját, megjelölve azokat a konkrét View-kat, amelyek újrarajzolást okoznak. iOS-ben az Instruments eszközt használják a Core Animation sablonnal — megjeleníti az FPS-t, a rétegek renderelési idejét és a képernyőn kívüli renderelések számát.
A Frame Rate termelési monitorozásához a Firebase Performance-et (Android) használják — a háttérben gyűjti a Frame Rate-et, és eszköz, operációs rendszer verzió és munkamenet szerint aggregálja. iOS-ben a MetricKit hasonló adatokat szolgáltat a MXAnimatoryMetric segítségével. Játékokhoz és Flutter alkalmazásokhoz a FrameTimingCallback-et (Flutter) és a Unity Profiler-t használják. Fontos, hogy ne az átlagos Frame Rate-et mérjük, hanem a percentiliseket: P50, P90 és P99. Egy alkalmazás átlagosan 55 fps-t mutathat, de P99 = 30 fps lehet — ez azt jelenti, hogy az idő 1%-ában a felhasználók erős akadozást látnak, és ez elegendő a negatív értékelésekhez.
A Dart példa bemutatja, hogyan lehet feliratkozni a FrameTimingCallback-ra Flutter-ben, és naplózni a kihagyott képkockák számát. A callback minden befejezett képkocka után aktiválódik.
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}");
}
}
A Frame Rate optimalizálása a renderelési csővezeték szűk keresztmetszeteinek azonosításával kezdődik. A Layout szakaszban a fő problémák a View hierarchia túlzott egymásba ágyazása, relatív Layout-ok használata (RelativeLayout sok szabállyal) és a gyakori requestLayout hívások. Megoldás — ConstraintLayout vagy lapos hierarchia használata, az 5–6 szintnél mélyebb egymásba ágyazás kerülése. A Draw szakaszban — újrarajzolás (overdraw): amikor egy pixelt többször rajzolnak meg képkockánként. Például egy Activity fehér háttere egy áttetsző fragment alatt, amely alatt még egy réteg van — minden pixelt háromszor rajzolnak meg. A Debug GPU Overdraw eszköz színjelzéssel mutatja a problémás területeket. Javasolt az overdraw 2x vagy alacsonyabb szinten tartása.
iOS-ben a fő problémák a nehéz cornerRadius és masksToBounds — ezek képernyőn kívüli renderelést (offscreen rendering) okoznak, ahol a Core Animation ideiglenes puffert hoz létre, abba rajzol, majd az eredményt a képernyőre másolja. Az offscreen rendering könnyen észrevehető az Instruments Core Animation-ben: ha a Renderer sor piros — probléma van. Megoldás — UIImageView használata előre levágott képekkel a cornerRadius helyett, a groupOpacity és a shouldRasterize kerülése szükségtelenül. Mindkét platform esetében kritikus az invalidate() és setNeedsDisplay() hívások számának minimalizálása — minden ilyen hívás elindítja a nézet teljes újrarajzolási ciklusát.
A kód a RelativeLayout mély egymásba ágyazásának lecserélését mutatja be a ConstraintLayout lapos struktúrájára. Az egymásba ágyazási szint 4-ről 1-re csökkentése 30–50%-kal rövidíti a Layout időt.
// Példa: lapos struktúra ConstraintLayout segítségével
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
// adatok kötése a teljes konténer újrarajzolása nélkül
}
}
A modern mobilalkalmazások egyre gyakrabban használnak adaptív Frame Rate-et — egy olyan rendszert, amely dinamikusan igazítja a célfrekvenciát az aktuális forgatókönyvhöz. Gyors görgetéskor a lista 120 fps-t igényel a simasághoz, statikus képernyőnél 60 fps vagy akár 30 fps is elegendő videóhoz. Androidban az adaptáció a Choreographer.setFrameInterval (API 33+) és a Window.setFrameRate segítségével valósul meg. A fejlesztő jelezheti a rendszernek a kívánt frekvenciát: setPreferredRefreshRate a SurfaceView-ben vagy setFrameRate a Window-ban. Az iOS automatikusan kezeli a frekvenciát a ProMotion segítségével, de a fejlesztő explicit módon beállíthatja a preferredFramesPerSecond értéket a CADisplayLink számára.
A dinamikus Frame Rate különösen fontos a játékok és animációs alkalmazások számára. A Google adatai szerint a Frame Rate 120-ról 60 Hz-re csökkentése statikus képernyőn akár 30–40% GPU-energiát takarít meg. A simaság és az energiafogyasztás közötti legjobb egyensúly eléréséhez javasolt: mérni a tényleges Frame Rate-et különböző forgatókönyvekben, beállítani a cél fps-t a jelenettől függően (játék — 60, menü — 30, videó — 24), és Lifecycle-aware komponenseken keresztül váltani a módokat, hogy az alkalmazás minimalizáláskor ne pazarolja az erőforrásokat 120 fps renderelésére a háttérben.
A Swift kód beállítja a preferredFramesPerSecond értéket a CADisplayLink számára iOS-ben. Görgetéskor a frekvencia 120 Hz-re emelkedik, megálláskor — 60 Hz-re csökken.
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() {
// animáció frissítése
}
}
Gyakran ismételt kérdések
Mobilalkalmazások esetében a cél Frame Rate 60 fps (16.6 ms képkockánként). 120 Hz-es kijelzős eszközöknél 120 fps kívánatos. A 30 fps alatti értékek észrevehetően rontják a felhasználói élményt.
Frame Rate — hány képkockát renderel másodpercenként az alkalmazás. Refresh Rate — másodpercenként hányszor frissíti fizikailag a kijelző a képet. Amikor a Frame Rate alacsonyabb a Refresh Rate-nél, a kijelző megismétli az utolsó képkockát.
Használja a GPU Profiling-ot a Developer Options-ben, az Android Studio Profiler-t vagy a Firebase Performance-ot. Programozott méréshez — Choreographer.FrameCallback a képkockák közötti intervallum kiszámításával.
Overdraw — ugyanazon pixel többszöri megrajzolása képkockánként. Minden további réteg növeli a Draw fázis idejét és csökkenti a Frame Rate-et. Az optimális overdraw 2x, a kritikus — 4x és magasabb.
Statikus tartalomnál a Dynamic Frame Rate 30–60 Hz-re csökkenti a frekvenciát, 30–40%-kal csökkentve a GPU terhelését. Görgetéskor a frekvencia 90–120 Hz-re emelkedik a simaság érdekében.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is