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 που απομονώνει την απόδοση από την κύρια εφαρμογή. Εάν η εφαρμογή μπλοκάρει το κύριο νήμα, ο 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 στο παρασκήνιο και το συγκεντρώνει ανά συσκευή, έκδοση OS και συνεδρία. Στο 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 κάτω από ημιδιαφανές fragment, κάτω από το οποίο υπάρχει άλλο στρώμα — κάθε εικονοστοιχείο σχεδιάζεται τρεις φορές. Το εργαλείο Debug GPU Overdraw δείχνει τις προβληματικές ζώνες με χρωματική ένδειξη. Συνιστάται η διατήρηση του overdraw στο επίπεδο 2x ή χαμηλότερο.

Στο iOS, τα κύρια προβλήματα είναι τα βαριά cornerRadius και masksToBounds — προκαλούν απόδοση εκτός οθόνης (offscreen rendering), όπου το Core Animation δημιουργεί προσωρινή μνήμη, σχεδιάζει σε αυτήν και στη συνέχεια αντιγράφει το αποτέλεσμα στην οθόνη. Η απόδοση εκτός οθόνης είναι εύκολα ορατή στο 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.

Το Dynamic Frame Rate είναι ιδιαίτερα σημαντικό για παιχνίδια και εφαρμογές με κινούμενα σχέδια. Σύμφωνα με δεδομένα Google, η μείωση του Frame Rate από 120 σε 60 Hz σε στατική οθόνη εξοικονομεί έως 30–40% ενέργειας GPU. Για την επίτευξη της καλύτερης ισορροπίας μεταξύ ομαλότητας και κατανάλωσης ενέργειας, συνιστάται: μέτρηση του πραγματικού Frame Rate σε διαφορετικά σενάρια, ρύθμιση του fps-στόχου ανάλογα με τη σκηνή (παιχνίδι — 60, μενού — 30, βίντεο — 24) και εναλλαγή λειτουργιών μέσω Lifecycle-aware components, ώστε η εφαρμογή όταν ελαχιστοποιείται να μην σπαταλά πόρους για απόδοση 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 και άνω.

Πώς εξοικονομεί μπαταρία το Dynamic 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) για υψηλό ρυθμό ανανέωσης.
  • Τα χαμένα καρέ προκαλούν Jank — ορατά τραυλίσματα που υποβαθμίζουν την εμπειρία χρήστη.
  • Κύριες αιτίες χαμηλού Frame Rate — υπερβολική ένθεση View, overdraw και απόδοση εκτός οθόνης.
  • Ο Choreographer (Android) και το CADisplayLink (iOS) συγχρονίζουν την απόδοση με VSync.
  • Το προσαρμοστικό Frame Rate εξισορροπεί ομαλότητα και κατανάλωση ενέργειας, μειώνοντας το φορτίο GPU έως 40%.
  • Η προφιλοποίηση Frame Rate — πρώτο βήμα για βελτιστοποίηση απόδοσης εφαρμογής κινητού.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης