Frame Rate у мобилним апликацијама — шта је то, fps и како га повећати

Аутор: IT Sectr Објављено: 2026-03-31 Време читања: 10 мин

Frame Rate — је број кадрова које графички систем приказује у једној секунди. У мобилним апликацијама фрејм рејт директно одређује глаткоћу анимација, скроловања и прелаза између екрана. Према подацима Android Developers, 2025, циљни Frame Rate износи 60 fps за стандардне дисплеје и 120 fps за уређаје са високом фреквенцијом освежавања. Одступање од циљне вредности доводи до визуелних застоја и погоршања корисничког искуства.

Главно

  • Frame Rate — број кадрова у секунди (fps) који одређује глаткоћу UI.
  • Стандардни циљни Frame Rate — 60 fps, одговара 16.6 ms по кадру.
  • Уређаји са 120 Hz дисплејима захтевају 120 fps (8.3 ms по кадру).
  • Пропуштени кадрови изазивају Jank — приметне застоје анимације.
  • Профилисање Frame Rate — први корак ка оптимизацији перформанси UI.

Шта је Frame Rate

Frame Rate (фрејм рејт) — је метрика мерена у кадровима у секунди (fps) која показује колико пута у секунди апликација ажурира слику на екрану. Људско око перципира покрет као гладак од 24 fps (кино), али за интерактивни UI потребно је минимално 60 fps како би се додири и анимације осећали тренутно. Сваки кадар је комплетан циклус: обрада корисничког уноса, израчунавање Layout, рендеринг View хијерархије и приказ на екрану. Ако било која од фаза премаши додељени буџет времена (16.6 ms при 60 fps), кадар се пропушта и корисник види застој.

Важно је разликовати Frame Rate апликације од фреквенције освежавања дисплеја (Refresh Rate). Фреквенција освежавања је карактеристика екрана: колико пута у секунди дисплеј физички освежава слику (60, 90, 120 или 144 Hz). Frame Rate — колико кадрова у секунди апликација успева да рендерује. Ако апликација производи 60 fps при дисплеју од 120 Hz, сваки други кадар ће бити дуплиран — слика ће остати глатка, али не толико реагивна колико би могла бити. Према Google I/O 2023, модерни флагмани могу да одржавају 120 fps у једноставним UI сценаријима, али у тешким (игре, сложене листе) фреквенција пада на 40–60 fps.

Како ради рендеринг кадрова

Рендеринг кадра у мобилној апликацији пролази кроз цевовод од неколико фаза. У Android-у цевовод укључује: обраду уноса (Input), анимацију (Animation), мерење и распоред (Layout), цртање (Draw), синхронизацију са GPU и приказ на екрану (Swap). Свака фаза се извршава на CPU или GPU, а укупно време свих фаза не сме да премаши буџет кадра. За 60 fps буџет је 16.6 ms, за 120 fps — 8.3 ms. Choreographer (Android) и CADisplayLink (iOS) синхронизују рендеринг са вертикалним освежавањем дисплеја (VSync), гарантујући да се кадар приказује само у тренутку освежавања екрана, избегавајући цепање слике (tearing).

У iOS-у цевовод је сличан: Run Loop обрађује догађаје, Core Animation израчунава слојеве, Render Server (одвојени процес) рендерује и шаље кадар на GPU. Разлика iOS-а — одвојени процес Render Server који изолује рендеринг од главне апликације. Ако апликација блокира main thread, Render Server и даље може да прикаже последњи познати кадар, али анимације ће се зауставити. Ако Render Server сам не стигне — GPU мирује и Frame Rate опада. Према Apple WWDC 2022, најчешћи узроци ниског Frame Rate у iOS-у су прекомерно угњежђавање CALayer, тешки shadowPath и рендеринг ван екрана (offscreen rendering).

Праћење кадрова кроз Choreographer

Код у Kotlin-у се претплаћује на Choreographer.FrameCallback и бележи стварно време између кадрова. Ако интервал прелази 16.6 ms — бележи се пропуштени кадар.

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

Фреквенција освежавања дисплеја и Frame Rate

Refresh Rate (фреквенција освежавања) — хардверска карактеристика дисплеја која одређује колико пута у секунди екран физички прецртава слику. Стандардни дисплеји имају 60 Hz, модерни флагмани — 90, 120 или 144 Hz. Frame Rate апликације може бити нижи, једнак или виши од фреквенције освежавања (у последњем случају вишак кадрова се одбацује). Идеалан сценарио — Frame Rate се поклапа са Refresh Rate: сваки хардверски циклус добија нови кадар од апликације и покрет је максимално гладак. Ако је Frame Rate нижи, дисплеј понавља последњи кадар, што се перципира као микро-застоји (stutter).

Android и iOS подржавају динамичко пребацивање фреквенције освежавања. Android 12+ користи Smart Refresh Rate: при скроловању систем подиже фреквенцију на 120 Hz, при статичном садржају смањује на 60 Hz ради уштеде батерије. iOS ProMotion (iPhone 13 Pro и новији) ради слично — фреквенција варира од 10 до 120 Hz у зависности од садржаја. Програмер треба да провери да ли уређај подржава високу фреквенцију и да прилагоди буџет времена по кадру. Ако апликација не стигне да рендерује кадар за 8.3 ms (за 120 Hz), боље је принудно радити на 60 Hz — то ће обезбедити стабилан Frame Rate без пропуштених кадрова.

Тип дисплејаRefresh RateБуџет по кадруУређаји
Стандардни60 Hz16.6 msВећина Android/iOS
Високи90 Hz11.1 msOnePlus, Pixel 6+
Флагмански120 Hz8.3 msiPhone Pro, Galaxy S22+
Гејминг144 Hz6.9 msROG Phone, Nubia RedMagic

Алати за мерење Frame Rate

За мерење Frame Rate у мобилним апликацијама доступни су како уграђени алати платформи, тако и екстерни профилери. У Android-у главни алат је GPU Profiling (Developer Options → Profile GPU Rendering) који приказује временску скалу сваког кадра са раздвајањем по фазама (Draw, Prepare, Process, Execute). Детаљнију анализу пружа Android Studio Profiler — бележи комплетан профил рендеринга са навођењем конкретних View које изазивају прецртавање. У iOS-у се користи Instruments са шаблоном Core Animation — приказује FPS, време рендеринга слојева и број рендеринга ван екрана.

За праћење Frame Rate у продукцији користи се Firebase Performance (Android) — прикупља Frame Rate у позадини и агрегира по уређајима, верзијама ОС и сесијама. У iOS-у MetricKit пружа сличне податке путем MXAnimatoryMetric. За игре и Flutter апликације користе се FrameTimingCallback (Flutter) и Unity Profiler. Важно је мерити не просечан Frame Rate, већ перцентиле: P50, P90 и P99. Апликација може да показује просечних 55 fps, али да има P99 = 30 fps — то значи да 1% времена корисници виде јаке застоје и то је довољно за негативне рецензије.

Мерење Frame Rate у Flutter-у

Пример у Dart-у показује како се претплатити на FrameTimingCallback у Flutter-у и бележити број пропуштених кадрова. Callback се покреће након сваког завршеног кадра.

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}");
    }
}

Оптимизација фрејм рејта

Оптимизација Frame Rate почиње идентификацијом уских грла у цевоводу рендеринга. У фази Layout главни проблеми су прекомерно угњежђавање View хијерархије, коришћење релативних Layout-а (RelativeLayout са великим бројем правила) и чести позиви requestLayout. Решење — коришћење ConstraintLayout или равне хијерархије, избегавање угњежђавања више од 5–6 нивоа. У фази Draw — прецртавање (overdraw): када се пиксел црта неколико пута по кадру. На пример, бела позадина Activity испод полупрозирног фрагмента испод којег је још један слој — сваки пиксел се црта три пута. Алат Debug GPU Overdraw приказује проблематичне зоне бојом. Препоручује се одржавање overdraw на нивоу 2x или нижем.

У iOS-у главни проблеми су тешки cornerRadius и masksToBounds — изазивају рендеринг ван екрана (offscreen rendering), при којем Core Animation ствара привремени бафер, црта у њега, затим копира резултат на екран. Offscreen rendering се лако примећује у Instruments Core Animation: ако је линија Renderer црвена — постоје проблеми. Решење — коришћење UIImageView са унапред исеченим сликама уместо cornerRadius, избегавање groupOpacity и shouldRasterize без крајње нужде. За обе платформе кључно је минимизирати број позива invalidate() и setNeedsDisplay() — сваки такав позив покреће комплетан циклус прецртавања приказа.

Оптимизација хијерархије у Android-у

Код демонстрира замену дубоког угњежђавања RelativeLayout равном структуром ConstraintLayout. Смањење нивоа угњежђавања са 4 на 1 скраћује време Layout за 30–50%.

kotlin
// Пример: равна структура кроз 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
        // повезивање података без прецртавања целог контејнера
    }
}

Адаптивне фреквенције и Dynamic Frame Rate

Модерне мобилне апликације све чешће користе адаптивни Frame Rate — систем који динамички прилагођава циљну фреквенцију тренутном сценарију. При брзом скроловању листа захтева 120 fps за глаткоћу, при статичном екрану довољно је 60 fps или чак 30 fps за видео. У Android-у адаптација се реализује кроз Choreographer.setFrameInterval (API 33+) и Window.setFrameRate. Програмер може да назначи систему жељену фреквенцију: setPreferredRefreshRate у SurfaceView или setFrameRate у Window. iOS аутоматски управља фреквенцијом кроз ProMotion, али програмер може експлицитно да подеси preferredFramesPerSecond за CADisplayLink.

Динамички Frame Rate је посебно важан за игре и апликације са анимацијама. Према Google подацима, смањење Frame Rate са 120 на 60 Hz на статичном екрану штеди до 30–40% енергије GPU. За постизање најбоље равнотеже између глаткоће и потрошње енергије препоручује се: мерити стварни Frame Rate у различитим сценаријима, подесити циљни fps у зависности од сцене (игра — 60, мени — 30, видео — 24) и пребацивати режиме кроз Lifecycle-aware компоненте, како апликација при свођењу не би трошила ресурсе на рендеринг 120 fps у позадини.

Подешавање жељеног Frame Rate

Код у Swift-у подешава preferredFramesPerSecond за CADisplayLink у iOS-у. При скроловању фреквенција расте на 120 Hz, при заустављању — опада на 60 Hz.

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() {
        // ажурирање анимације
    }
}

Често постављана питања

Који Frame Rate се сматра добрим за мобилну апликацију?

За мобилне апликације циљни Frame Rate — 60 fps (16.6 ms по кадру). За уређаје са дисплејима од 120 Hz пожељно је 120 fps. Вредности испод 30 fps приметно погоршавају корисничко искуство.

Чим се Frame Rate разликује од фреквенције освежавања дисплеја?

Frame Rate — колико кадрова у секунди апликација рендерује. Refresh Rate — колико пута у секунди дисплеј физички освежава слику. Када је Frame Rate нижи од Refresh Rate, дисплеј понавља последњи кадар.

Како измерити Frame Rate у Android-у?

Користите GPU Profiling у Developer Options, Android Studio Profiler или Firebase Performance. За програмско мерење — Choreographer.FrameCallback са израчунавањем интервала између кадрова.

Шта је overdraw и како утиче на Frame Rate?

Overdraw — прецртавање истог пиксела неколико пута по кадру. Сваки додатни слој повећава време Draw фазе и смањује Frame Rate. Оптималан overdraw је 2x, критичан — 4x и више.

Како динамички Frame Rate штеди батерију?

При статичном садржају Dynamic Frame Rate смањује фреквенцију на 30–60 Hz, смањујући оптерећење GPU за 30–40%. При скроловању фреквенција расте на 90–120 Hz ради глаткоће.

Резиме

  • Frame Rate — број кадрова у секунди који одређује глаткоћу UI и анимација.
  • Циљни Frame Rate — 60 fps (16.6 ms) за стандардне дисплеје, 120 fps (8.3 ms) за High Refresh Rate.
  • Пропуштени кадрови изазивају Jank — видљиве застоје који погоршавају корисничко искуство.
  • Главни узроци ниског Frame Rate — прекомерно угњежђавање View, overdraw и offscreen rendering.
  • Choreographer (Android) и CADisplayLink (iOS) синхронизују рендеринг са VSync.
  • Адаптивни Frame Rate балансира између глаткоће и потрошње енергије, смањујући оптерећење GPU до 40%.
  • Профилисање Frame Rate — први корак ка оптимизацији перформанси мобилне апликације.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође