Frame Rate a mobilalkalmazásokban — mi ez, fps és hogyan javítható

Szerző: IT Sectr Megjelenés: 2026-03-31 Olvasási idő: 10 perc

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 — a másodpercenkénti képkockák száma (fps), amely meghatározza a UI simaságát.
  • Szabványos cél Frame Rate — 60 fps, 16.6 ms-nak felel meg képkockánként.
  • A 120 Hz kijelzős eszközök 120 fps-t igényelnek (8.3 ms képkockánként).
  • A kihagyott képkockák Jank-ot — észrevehető animációs akadozást okoznak.
  • A Frame Rate profilozás — az első lépés a UI teljesítmény optimalizálásához.

Mi az a Frame Rate

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.

Hogyan működik a képkockák renderelése

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).

Képkockák nyomon követése Choreographer segítségével

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.

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

A kijelző frissítési frekvenciája és a Frame Rate

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ípusaRefresh RateKépkocka keretEszközök
Szabványos60 Hz16.6 msA legtöbb Android/iOS
Magas90 Hz11.1 msOnePlus, Pixel 6+
Zászlóshajó120 Hz8.3 msiPhone Pro, Galaxy S22+
Játék144 Hz6.9 msROG Phone, Nubia RedMagic

Frame Rate mérőeszközök

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.

Frame Rate mérés Flutter-ben

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.

dart
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 képkockasebesség optimalizálása

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.

Hierarchia optimalizálása Androidban

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.

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

Adaptív frekvenciák és Dynamic Frame Rate

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 kívánt Frame Rate beállítása

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.

swift
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

Milyen Frame Rate számít jónak egy mobilalkalmazás számára?

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.

Miben különbözik a Frame Rate a kijelző frissítési frekvenciájától?

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.

Hogyan mérhető a Frame Rate Androidban?

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.

Mi az overdraw és hogyan befolyásolja a Frame Rate-et?

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.

Hogyan takarít meg a Dynamic Frame Rate akkumulátort?

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

  • Frame Rate — a másodpercenkénti képkockák száma, amely meghatározza a UI és az animációk simaságát.
  • Cél Frame Rate — 60 fps (16.6 ms) szabványos kijelzőkhöz, 120 fps (8.3 ms) magas frissítési frekvenciához.
  • A kihagyott képkockák Jank-ot — látható akadozást okoznak, rontva a felhasználói élményt.
  • Az alacsony Frame Rate fő okai — a View túlzott egymásba ágyazása, overdraw és képernyőn kívüli renderelés.
  • A Choreographer (Android) és a CADisplayLink (iOS) szinkronizálja a renderelést a VSync-csel.
  • Az adaptív Frame Rate egyensúlyt teremt a simaság és az energiafogyasztás között, akár 40%-kal csökkentve a GPU terhelését.
  • A Frame Rate profilozás — az első lépés a mobilalkalmazás teljesítményének optimalizálásához.

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.

Projekt megbeszélése

Olvassa el is