Frame Rate dans les applications mobiles — définition, fps et comment l'améliorer

Auteur : IT Sectr Publié le : 2026-03-31 Temps de lecture : 10 min

Le Frame Rate est le nombre d'images qu'un système graphique affiche par seconde. Dans les applications mobiles, la fréquence d'images détermine directement la fluidité des animations, du défilement et des transitions entre écrans. Selon Android Developers, 2025, le Frame Rate cible est de 60 fps pour les écrans standard et de 120 fps pour les appareils à taux de rafraîchissement élevé. Un écart par rapport à la valeur cible entraîne un bégaiement visuel et une dégradation de l'expérience utilisateur.

Points clés

  • Frame Rate — nombre d'images par seconde (fps) qui détermine la fluidité de l'interface.
  • Le Frame Rate cible standard est 60 fps, correspondant à 16,6 ms par image.
  • Les appareils avec écrans 120 Hz nécessitent 120 fps (8,3 ms par image).
  • Les images perdues provoquent du Jank — un bégaiement visible des animations.
  • Profiler le Frame Rate est la première étape vers l'optimisation des performances de l'interface.

Qu'est-ce que le Frame Rate

Frame Rate (fréquence d'images) est une métrique mesurée en images par seconde (fps) qui indique combien de fois par seconde une application met à jour l'image à l'écran. L'œil humain perçoit le mouvement comme fluide à partir de 24 fps (cinéma), mais une interface interactive nécessite au moins 60 fps pour que les touches et les animations paraissent instantanées. Chaque image est un cycle complet : traitement de l'entrée utilisateur, calcul du Layout, rendu de la hiérarchie des vues et sortie vers l'écran. Si l'une de ces étapes dépasse le budget de temps alloué (16,6 ms à 60 fps), l'image est sautée et l'utilisateur voit un bégaiement.

Il est important de distinguer le Frame Rate de l'application du taux de rafraîchissement de l'écran (Refresh Rate). Le taux de rafraîchissement est une caractéristique matérielle : combien de fois par seconde l'écran met physiquement à jour l'image (60, 90, 120 ou 144 Hz). Le Frame Rate est le nombre d'images par seconde que l'application parvient à rendre. Si l'application produit 60 fps sur un écran 120 Hz, une image sur deux sera dupliquée — l'image reste fluide mais pas aussi réactive qu'elle pourrait l'être. Selon Google I/O 2023, les flagships modernes peuvent maintenir 120 fps dans des scénarios d'interface simples, mais sous charge lourde (jeux, listes complexes) le taux tombe à 40–60 fps.

Comment fonctionne le rendu des images

Le rendu des images dans une application mobile passe par un pipeline de plusieurs étapes. Sous Android, le pipeline comprend : le traitement des entrées (Input), l'animation (Animation), la mesure et la disposition (Layout), le dessin (Draw), la synchronisation GPU et la sortie écran (Swap). Chaque étape s'exécute sur le CPU ou le GPU, et le temps total de toutes les étapes ne doit pas dépasser le budget de l'image. Pour 60 fps, le budget est de 16,6 ms, pour 120 fps — 8,3 ms. Choreographer (Android) et CADisplayLink (iOS) synchronisent le rendu avec l'intervalle de blanking vertical de l'écran (VSync), garantissant que l'image n'est affichée qu'au moment du rafraîchissement de l'écran, évitant le tearing.

Sous iOS, le pipeline est similaire : Run Loop traite les événements, Core Animation calcule les couches, Render Server (un processus séparé) effectue le rendu et envoie l'image au GPU. La différence sous iOS est le processus dédié Render Server, qui isole le rendu de l'application principale. Si l'application bloque le thread principal, Render Server peut toujours dessiner la dernière image connue, mais les animations s'arrêteront. Si Render Server lui-même ne peut pas suivre — le GPU reste inactif et le Frame Rate chute. Selon l'Apple WWDC 2022, les causes les plus fréquentes d'un faible Frame Rate sous iOS sont l'imbrication excessive de CALayer, les shadowPath lourds et le rendu hors écran.

Suivi des images via Choreographer

Le code Kotlin s'abonne à Choreographer.FrameCallback et enregistre le temps réel entre les images. Si l'intervalle dépasse 16,6 ms, une image perdue est enregistrée.

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

Taux de rafraîchissement de l'écran et Frame Rate

Refresh Rate (taux de rafraîchissement) est une caractéristique matérielle de l'écran qui détermine combien de fois par seconde l'affichage redessine physiquement l'image. Les écrans standard ont 60 Hz, les flagships modernes ont 90, 120 ou 144 Hz. Le Frame Rate de l'application peut être inférieur, égal ou supérieur au taux de rafraîchissement (dans ce dernier cas, les images en excès sont ignorées). Le scénario idéal est lorsque le Frame Rate coïncide avec le Refresh Rate : chaque cycle matériel reçoit une nouvelle image de l'application et le mouvement est maximalement fluide. Si le Frame Rate est inférieur, l'écran répète la dernière image, ce qui est perçu comme un micro-bégaiement.

Android et iOS prennent en charge le changement dynamique du taux de rafraîchissement. Android 12+ utilise Smart Refresh Rate : lors du défilement, le système élève le taux à 120 Hz, sur du contenu statique, il le réduit à 60 Hz pour économiser la batterie. iOS ProMotion (iPhone 13 Pro et plus récents) fonctionne de manière similaire — le taux varie de 10 à 120 Hz selon le contenu. Le développeur doit vérifier si l'appareil prend en charge un taux élevé et adapter le budget de temps par image. Si l'application ne peut pas rendre une image en 8,3 ms (pour 120 Hz), il est préférable de forcer 60 Hz — cela garantira un Frame Rate stable sans images perdues.

Type d'écranRefresh RateBudget par imageAppareils
Standard60 Hz16,6 msLa plupart Android/iOS
Élevé90 Hz11,1 msOnePlus, Pixel 6+
Flagship120 Hz8,3 msiPhone Pro, Galaxy S22+
Jeu144 Hz6,9 msROG Phone, Nubia RedMagic

Outils de mesure du Frame Rate

Les outils intégrés des plateformes ainsi que les profileurs tiers sont disponibles pour mesurer le Frame Rate dans les applications mobiles. Sous Android, l'outil principal est GPU Profiling (Developer Options → Profile GPU Rendering), qui montre une chronologie de chaque image décomposée par étapes (Draw, Prepare, Process, Execute). Une analyse plus détaillée est fournie par Android Studio Profiler — il enregistre un profil de rendu complet indiquant les vues spécifiques qui provoquent des redessins. Sous iOS, on utilise Instruments avec le modèle Core Animation — il affiche le FPS, le temps de rendu des couches et le nombre de rendus hors écran.

Pour la surveillance du Frame Rate en production, Firebase Performance (Android) est utilisé — il collecte le Frame Rate en arrière-plan et l'agrège par appareil, version d'OS et session. Sous iOS, MetricKit fournit des données similaires via MXAnimatoryMetric. Pour les jeux et les applications Flutter, on utilise FrameTimingCallback (Flutter) et Unity Profiler. Il est important de mesurer non pas le Frame Rate moyen mais les percentiles : P50, P90 et P99. Une application peut afficher une moyenne de 55 fps mais avoir un P99 de 30 fps — cela signifie que 1% du temps les utilisateurs voient un bégaiement sévère, suffisant pour des avis négatifs.

Mesure du Frame Rate dans Flutter

L'exemple Dart montre comment s'abonner à FrameTimingCallback dans Flutter et enregistrer le nombre d'images perdues. Le callback se déclenche après chaque image terminée.

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

Optimisation de la fréquence d'images

L'optimisation du Frame Rate commence par l'identification des goulots d'étranglement dans le pipeline de rendu. Dans la phase de Layout, les principaux problèmes sont l'imbrication excessive de la hiérarchie des vues, l'utilisation de layouts relatifs (RelativeLayout avec de nombreuses règles) et les appels fréquents à requestLayout. La solution consiste à utiliser ConstraintLayout ou une hiérarchie plate, en évitant les imbrications de plus de 5 à 6 niveaux. Dans la phase de Draw — l'overdraw : lorsqu'un pixel est dessiné plusieurs fois par image. Par exemple, un fond d'Activity blanc sous un fragment semi-transparent, sous lequel se trouve encore une couche — chaque pixel est dessiné trois fois. L'outil Debug GPU Overdraw montre les zones problématiques avec un code couleur. Il est recommandé de maintenir l'overdraw à 2x ou moins.

Sous iOS, les principaux problèmes sont cornerRadius et masksToBounds lourds — ils provoquent un rendu hors écran, où Core Animation crée un tampon temporaire, dessine dedans, puis copie le résultat à l'écran. Le rendu hors écran est facilement repérable dans Instruments Core Animation : si la ligne Renderer est rouge — il y a des problèmes. La solution consiste à utiliser UIImageView avec des images pré-recadrées au lieu de cornerRadius, à éviter groupOpacity et shouldRasterize sauf en cas d'absolue nécessité. Pour les deux plateformes, il est essentiel de minimiser le nombre d'appels à invalidate() et setNeedsDisplay() — chacun de ces appels déclenche un cycle complet de redessin de la vue.

Optimisation de la hiérarchie sous Android

Le code montre le remplacement d'une imbrication profonde de RelativeLayout par une structure plate avec ConstraintLayout. La réduction du niveau d'imbrication de 4 à 1 réduit le temps de Layout de 30 à 50%.

kotlin
// Exemple : structure plate via 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
        // lier les données sans redessiner tout le conteneur
    }
}

Fréquences adaptatives et Dynamic Frame Rate

Les applications mobiles modernes utilisent de plus en plus le Frame Rate adaptatif — un système qui ajuste dynamiquement la fréquence cible en fonction du scénario actuel. Un défilement rapide nécessite 120 fps pour la fluidité, tandis qu'un écran statique n'a besoin que de 60 fps voire 30 fps pour une vidéo. Sous Android, l'adaptation est implémentée via Choreographer.setFrameInterval (API 33+) et Window.setFrameRate. Le développeur peut spécifier une fréquence préférée : setPreferredRefreshRate dans SurfaceView ou setFrameRate dans Window. iOS gère automatiquement la fréquence via ProMotion, mais le développeur peut définir explicitement preferredFramesPerSecond pour CADisplayLink.

Le Dynamic Frame Rate est particulièrement important pour les jeux et les applications avec animations. Selon Google, réduire le Frame Rate de 120 à 60 Hz sur un écran statique économise jusqu'à 30 à 40% d'énergie GPU. Pour atteindre le meilleur équilibre entre fluidité et consommation d'énergie, il est recommandé de : mesurer le Frame Rate réel dans différents scénarios, définir les fps cibles en fonction de la scène (jeu — 60, menu — 30, vidéo — 24), et changer les modes via des composants Lifecycle-aware pour que l'application ne gaspille pas de ressources à rendre du 120 fps en arrière-plan lorsqu'elle est minimisée.

Définition du Frame Rate préféré

Le code Swift définit preferredFramesPerSecond pour CADisplayLink sous iOS. Lors du défilement, la fréquence monte à 120 Hz, à l'arrêt elle descend à 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() {
        // mise à jour d'animation
    }
}

Questions fréquentes

Quel Frame Rate est considéré comme bon pour une application mobile ?

Pour les applications mobiles, le Frame Rate cible est de 60 fps (16,6 ms par image). Pour les appareils avec écrans 120 Hz, 120 fps sont souhaitables. Les valeurs inférieures à 30 fps dégradent notablement l'expérience utilisateur.

En quoi le Frame Rate diffère-t-il du taux de rafraîchissement de l'écran ?

Frame Rate — nombre d'images par seconde que l'application rend. Refresh Rate — nombre de fois par seconde que l'écran met physiquement à jour l'image. Lorsque le Frame Rate est inférieur au Refresh Rate, l'écran duplique la dernière image.

Comment mesurer le Frame Rate sous Android ?

Utilisez GPU Profiling dans les options développeur, Android Studio Profiler ou Firebase Performance. Pour une mesure programmatique — Choreographer.FrameCallback avec calcul de l'intervalle entre les images.

Qu'est-ce que l'overdraw et comment affecte-t-il le Frame Rate ?

Overdraw — dessiner un même pixel plusieurs fois par image. Chaque couche supplémentaire augmente le temps de la phase Draw et réduit le Frame Rate. L'overdraw optimal est de 2x, le critique est de 4x et plus.

Comment le Dynamic Frame Rate économise-t-il la batterie ?

Sur du contenu statique, le Dynamic Frame Rate réduit la fréquence à 30–60 Hz, diminuant la charge du GPU de 30 à 40%. Lors du défilement, la fréquence monte à 90–120 Hz pour la fluidité.

Résumé

  • Frame Rate — nombre d'images par seconde qui détermine la fluidité de l'interface et des animations.
  • Frame Rate cible — 60 fps (16,6 ms par image) pour les écrans standard, 120 fps (8,3 ms) pour les taux de rafraîchissement élevés.
  • Les images perdues provoquent du Jank — un bégaiement visible qui dégrade l'expérience utilisateur.
  • Les principales causes d'un faible Frame Rate sont l'imbrication excessive des vues, l'overdraw et le rendu hors écran.
  • Choreographer (Android) et CADisplayLink (iOS) synchronisent le rendu avec VSync.
  • Le Frame Rate adaptatif équilibre fluidité et consommation d'énergie, réduisant la charge du GPU jusqu'à 40%.
  • Profiler le Frame Rate est la première étape pour optimiser les performances d'une application mobile.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi