Frame Rate — qrafik sistemin bir saniyədə göstərdiyi kadrların sayıdır. Mobil tətbiqatlarda kadr tezliyi animasiyaların, sürüşdürmənin və ekranlar arası keçidlərin hamarlığını birbaşa müəyyən edir. Android Developers, 2025 məlumatlarına görə, hədəf Frame Rate standart displeylər üçün 60 fps, yüksək yenilənmə tezliyi olan cihazlar üçün isə 120 fps təşkil edir. Hədəf dəyərdən kənarlaşma vizual ləngimələrə və istifadəçi təcrübəsinin pisləşməsinə səbəb olur.
Əsas məqamlar
Frame Rate (kadr tezliyi) — saniyədə kadrlarla (fps) ölçülən metrikadır və tətbiqin ekrandakı təsviri saniyədə neçə dəfə yenilədiyini göstərir. İnsan gözü hərəkəti 24 fps-dən (kino) başlayaraq hamar qəbul edir, lakin interaktiv UI üçün toxunuşların və animasiyaların ani hiss olunması üçün minimum 60 fps tələb olunur. Hər bir kadr tam bir dövrdür: istifadəçi girişinin işlənməsi, Layout hesablanması, View iyerarxiyasının render edilməsi və ekrana çıxarılması. Mərhələlərdən hər hansısı ayrılmış vaxt büdcəsini (60 fps-də 16.6 ms) keçərsə, kadr buraxılır və istifadəçi ləngimə görür.
Tətbiqin Frame Rate-ini displeyin yenilənmə tezliyindən (Refresh Rate) fərqləndirmək vacibdir. Yenilənmə tezliyi ekranın xarakteristikasıdır: displeyin saniyədə neçə dəfə fiziki olaraq təsviri yenilədiyi (60, 90, 120 və ya 144 Hz). Frame Rate — tətbiqin saniyədə neçə kadr render edə bildiyidir. Tətbiq 120 Hz displeydə 60 fps verirsə, hər ikinci kadr təkrarlanacaq — təsvir hamar qalacaq, lakin ola biləcəyi qədər həssas olmayacaq. Google I/O 2023 məlumatlarına görə, müasir flaqmanlar sadə UI ssenarilərində 120 fps saxlaya bilir, lakin ağır yüklərdə (oyunlar, mürəkkəb siyahılar) tezlik 40–60 fps-ə düşür.
Mobil tətbiqdə kadr renderi bir neçə mərhələdən ibarət konveyerdən keçir. Androiddə konveyerə daxildir: girişin işlənməsi (Input), animasiya (Animation), ölçmə və yerləşdirmə (Layout), çəkmə (Draw), GPU ilə sinxronizasiya və ekrana çıxarış (Swap). Hər mərhələ CPU və ya GPU-da yerinə yetirilir və bütün mərhələlərin ümumi vaxtı kadr büdcəsini keçməməlidir. 60 fps üçün býcə 16.6 ms, 120 fps üçün 8.3 ms-dir. Choreographer (Android) və CADisplayLink (iOS) renderi displeyin şaquli yenilənməsi (VSync) ilə sinxronlaşdırır, kadrın yalnız ekran yenilənməsi anında çıxarılmasını təmin edərək tearinqin (təsvirin qopması) qarşısını alır.
iOS-da konveyer oxşardır: Run Loop hadisələri emal edir, Core Animation təbəqələri hesablayır, Render Server (ayrı proses) render edir və kadrı GPU-ya göndərir. iOS-un fərqi — renderi əsas tətbiqdən təcrid edən ayrılmış Render Server prosesidir. Tətbiq main thread-i bloklayarsa, Render Server yenə də son məlum kadrı göstərə bilər, lakin animasiyalar dayanacaq. Render Server özü çatdıra bilməzsə — GPU boş dayanır və Frame Rate düşür. Apple WWDC 2022 məlumatlarına görə, iOS-da aşağı Frame Rate-in ən çox yayılmış səbəbləri həddindən artıq CALayer iç-içəliyi, ağır shadowPath və offscreen renderingdir.
Kotlin kodunda Choreographer.FrameCallback-ə abunə olunur və kadrlar arasındakı faktiki vaxt qeydə alınır. İnterval 16.6 ms-dən çox olarsa — buraxılmış kadr qeydə alınır.
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 (yenilənmə tezliyi) — displeyin saniyədə neçə dəfə təsviri fiziki olaraq yenidən çəkdiyini təyin edən aparat xarakteristikasıdır. Standart displeylər 60 Hz, müasir flaqmanlar — 90, 120 və ya 144 Hz-ə malikdir. Tətbiqin Frame Rate-i yenilənmə tezliyindən aşağı, bərabər və ya yüksək ola bilər (sonuncu halda artıq kadrlar atılır). İdeal ssenari — Frame Rate-in Refresh Rate ilə üst-üstə düşməsidir: hər aparat dövri tətbiqdən yeni kadr alır və hərəkət maksimum dərəcədə hamar olur. Frame Rate aşağı olarsa, displey son kadrı təkrarlayır, bu da mikro-ləngimələr (stutter) kimi qəbul edilir.
Android və iOS yenilənmə tezliyinin dinamik dəyişdirilməsini dəstəkləyir. Android 12+ Smart Refresh Rate istifadə edir: sürüşdürmə zamanı sistem tezliyi 120 Hz-ə qaldırır, statik məzmun zamanı batareyaya qənaət üçün 60 Hz-ə endirir. iOS ProMotion (iPhone 13 Pro və daha yeniləri) oxşar işləyir — tezlik məzmundan asılı olaraq 10-dan 120 Hz-ə qədər dəyişir. Tərtibatçı cihazın yüksək tezliyi dəstəklədiyini yoxlamalı və kadr vaxtı büdcəsini uyğunlaşdırmalıdır. Tətbiq 8.3 ms-də (120 Hz üçün) kadr render edə bilmirsə, məcburi olaraq 60 Hz-də işləmək daha yaxşıdır — bu, buraxılmış kadrlar olmadan sabit Frame Rate təmin edəcək.
| Displey növü | Refresh Rate | Kadr býcəsi | Cihazlar |
|---|---|---|---|
| Standart | 60 Hz | 16.6 ms | Əksər Android/iOS |
| Yüksək | 90 Hz | 11.1 ms | OnePlus, Pixel 6+ |
| Flaqman | 120 Hz | 8.3 ms | iPhone Pro, Galaxy S22+ |
| Oyun | 144 Hz | 6.9 ms | ROG Phone, Nubia RedMagic |
Mobil tətbiqlərdə Frame Rate ölçmək üçün həm platformaların daxili alətləri, həm də üçüncü tərəf profilerləri mövcuddur. Androiddə əsas vasitə GPU Profiling-dir (Developer Options → Profile GPU Rendering), o, hər kadrın mərhələlər üzrə bölgüsü ilə (Draw, Prepare, Process, Execute) vaxt miqyasını göstərir. Daha ətraflı təhlili Android Studio Profiler təmin edir — o, yenidən çəkməyə səbəb olan xüsusi View-ləri göstərən tam render profilini qeyd edir. iOS-da Instruments Core Animation şablonu ilə istifadə olunur — FPS, təbəqə render vaxtı və offscreen render sayını göstərir.
İstehsalatda Frame Rate monitorinqi üçün Firebase Performance (Android) istifadə olunur — o, Frame Rate-i fonda toplayır və cihazlar, ƏS versiyaları və sessiyalar üzrə aqreqasiya edir. iOS-da MetricKit MXAnimatoryMetric vasitəsilə oxşar məlumatlar təqdim edir. Oyunlar və Flutter tətbiqləri üçün FrameTimingCallback (Flutter) və Unity Profiler istifadə olunur. Orta Frame Rate deyil, persentilləri ölçmək vacibdir: P50, P90 və P99. Tətbiq orta 55 fps göstərə bilər, lakin P99 = 30 fps ola bilər — bu o deməkdir ki, vaxtın 1%-də istifadəçilər güclü ləngimələr görür və bu, mənfi rəylər üçün kifayətdir.
Dart dilində nümunə Flutter-da FrameTimingCallback-ə abunə olmağı və buraxılmış kadrların sayını qeydə almağı göstərir. Callback hər tamamlanmış kadrdan sonra işə düşür.
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 optimallaşdırılması render konveyerində darboğazların müəyyən edilməsi ilə başlayır. Layout mərhələsində əsas problemlər — View iyerarxiyasının həddindən artıq iç-içəliyi, nisbi Layout-lardan istifadə (çox sayda qaydaları olan RelativeLayout) və tez-tez requestLayout çağırışlarıdır. Həll yolu — ConstraintLayout və ya düz iyerarxiya istifadə etmək, 5–6 səviyyədən yuxarı iç-içəlikdən qaçmaqdır. Draw mərhələsində — overdraw (həddindən artıq çəkmə): pikselin kadr başına bir neçə dəfə çəkilməsi. Məsələn, yarımşəffaf fraqmentin altında Activity-nin ağ fonu, onun altında isə başqa təbəqə — hər piksel üç dəfə çəkilir. Debug GPU Overdraw aləti problemli zonaları rəng göstəriciləri ilə nümayiş etdirir. Overdraw-ı 2x və daha aşağı səviyyədə saxlamaq tövsiyə olunur.
iOS-da əsas problemlər — ağır cornerRadius və masksToBounds — onlar Core Animation-ın müvəqqəti bufer yaratdığı, içinə çəkdiyi və nəticəni ekrana köçürdüyü offscreen renderingə səbəb olur. Offscreen rendering-i Instruments Core Animation-da asanlıqla görmək olar: Renderer sətri qırmızıdırsa — problem var. Həll yolu — cornerRadius əvəzinə əvvəlcədən kəsilmiş şəkillərlə UIImageView istifadə etmək, zərurət olmadan groupOpacity və shouldRasterize-dən qaçmaq. Hər iki platforma üçün invalidate() və setNeedsDisplay() çağırışlarının sayını minimuma endirmək kritik önəm daşıyır — hər belə çağırış görünüşün tam yenidən çəkilmə dövrünü işə salır.
Kod RelativeLayout dərin iç-içəliyinin ConstraintLayout düz strukturu ilə əvəz edilməsini nümayiş etdirir. İç-içəlik səviyyəsinin 4-dən 1-ə endirilməsi Layout vaxtını 30–50% qısaltır.
// Nümunə: ConstraintLayout vasitəsilə düz struktur
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
// məlumatları bütün konteyneri yenidən çəkmədən bağlamaq
}
}
Müasir mobil tətbiqlər getdikcə daha çox adaptiv Frame Rate — hədəf tezliyi cari ssenariyə dinamik uyğunlaşdıran sistemdən istifadə edir. Sürətli sürüşdürmə zamanı siyahı hamarlıq üçün 120 fps tələb edir, statik ekranda 60 fps və ya hətta video üçün 30 fps kifayətdir. Androiddə adaptasiya Choreographer.setFrameInterval (API 33+) və Window.setFrameRate vasitəsilə həyata keçirilir. Tərtibatçı sistemə üstünlük verilən tezliyi göstərə bilər: SurfaceView-də setPreferredRefreshRate və ya Window-da setFrameRate. iOS avtomatik olaraq ProMotion vasitəsilə tezliyi idarə edir, lakin tərtibatçı CADisplayLink üçün preferredFramesPerSecond təyin edə bilər.
Dinamik Frame Rate xüsusilə oyunlar və animasiyalı tətbiqlər üçün vacibdir. Google məlumatlarına görə, statik ekranda Frame Rate-in 120-dən 60 Hz-ə endirilməsi GPU enerjisinin 30–40%-nə qənaət edir. Hamarlıq və enerji istehlakı arasında ən yaxşı tarazlığa nail olmaq üçün tövsiyə olunur: müxtəlif ssenarilərdə faktiki Frame Rate-i ölçmək, səhnədən asılı olaraq hədəf fps təyin etmək (oyun — 60, menyu — 30, video — 24) və rejimləri Lifecycle-aware komponentlər vasitəsilə dəyişmək ki, tətbiq kiçildildikdə fonda 120 fps renderinə resurs sərf etməsin.
Swift-də kod iOS-da CADisplayLink üçün preferredFramesPerSecond təyin edir. Sürüşdürmə zamanı tezlik 120 Hz-ə qalxır, dayandıqda — 60 Hz-ə enir.
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() {
// animasiya yenilənməsi
}
}
Tez-tez verilən suallar
Mobil tətbiqlər üçün hədəf Frame Rate 60 fps (kadr başına 16.6 ms)-dir. 120 Hz displeyli cihazlar üçün 120 fps arzuolunandır. 30 fps-dən aşağı dəyərlər istifadəçi təcrübəsini nəzərəçarpan şəkildə pisləşdirir.
Frame Rate — tətbiqin saniyədə neçə kadr render etdiyi. Refresh Rate — displeyin saniyədə neçə dəfə təsviri fiziki olaraq yenilədiyi. Frame Rate Refresh Rate-dən aşağı olduqda, displey son kadrı təkrarlayır.
GPU Profiling (Developer Options), Android Studio Profiler və ya Firebase Performance istifadə edin. Proqram ölçümü üçün — kadrlar arası intervalı hesablayan Choreographer.FrameCallback.
Overdraw — bir pikselin kadr başına bir neçə dəfə çəkilməsi. Hər əlavə təbəqə Draw mərhələsinin vaxtını artırır və Frame Rate-i aşağı salır. Optimal overdraw 2x, kritik — 4x və daha yüksəkdir.
Statik məzmun zamanı Dynamic Frame Rate tezliyi 30–60 Hz-ə endirir, GPU yükünü 30–40% azaldır. Sürüşdürmə zamanı tezlik hamarlıq üçün 90–120 Hz-ə qalxır.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun