Frame Rate em aplicativos móveis — o que é, fps e como melhorar

Autor: IT Sectr Publicado: 2026-03-31 Tempo de leitura: 10 min

Frame Rate é o número de quadros que um sistema gráfico exibe por segundo. Em aplicativos móveis, a taxa de quadros determina diretamente a suavidade das animações, rolagem e transições entre telas. De acordo com Android Developers, 2025, o Frame Rate alvo é de 60 fps para telas padrão e 120 fps para dispositivos com alta taxa de atualização. O desvio do valor alvo leva a engasgos visuais e degradação da experiência do usuário.

Principais pontos

  • Frame Rate — número de quadros por segundo (fps) que determina a suavidade da interface.
  • O Frame Rate alvo padrão é 60 fps, correspondente a 16.6 ms por quadro.
  • Dispositivos com telas de 120 Hz exigem 120 fps (8.3 ms por quadro).
  • Quadros perdidos causam Jank — engasgos perceptíveis nas animações.
  • Perfilar o Frame Rate é o primeiro passo para otimizar o desempenho da interface.

O que é Frame Rate

Frame Rate (taxa de quadros) é uma métrica medida em quadros por segundo (fps) que indica quantas vezes por segundo um aplicativo atualiza a imagem na tela. O olho humano percebe o movimento como suave a partir de 24 fps (cinema), mas uma interface interativa requer pelo menos 60 fps para que toques e animações pareçam instantâneos. Cada quadro é um ciclo completo: processamento da entrada do usuário, cálculo do Layout, renderização da hierarquia de Views e saída para a tela. Se qualquer uma dessas etapas exceder o orçamento de tempo alocado (16.6 ms a 60 fps), o quadro é pulado e o usuário vê um engasgo.

É importante distinguir entre o Frame Rate do aplicativo e a taxa de atualização da tela (Refresh Rate). A taxa de atualização é uma característica do hardware: quantas vezes por segundo a tela atualiza fisicamente a imagem (60, 90, 120 ou 144 Hz). O Frame Rate é quantos quadros por segundo o aplicativo consegue renderizar. Se o aplicativo produz 60 fps em uma tela de 120 Hz, cada segundo quadro será duplicado — a imagem permanece suave, mas não tão responsiva quanto poderia ser. De acordo com o Google I/O 2023, os flagships modernos conseguem manter 120 fps em cenários simples de interface, mas sob carga pesada (jogos, listas complexas) a taxa cai para 40–60 fps.

Como funciona a renderização de quadros

A renderização de quadros em um aplicativo móvel passa por um pipeline de várias etapas. No Android, o pipeline inclui: processamento de entrada (Input), animação (Animation), medição e disposição (Layout), desenho (Draw), sincronização com GPU e saída para tela (Swap). Cada etapa é executada na CPU ou GPU, e o tempo total de todas as etapas não deve exceder o orçamento do quadro. Para 60 fps o orçamento é de 16.6 ms, para 120 fps — 8.3 ms. Choreographer (Android) e CADisplayLink (iOS) sincronizam a renderização com o intervalo de blanking vertical da tela (VSync), garantindo que o quadro seja exibido apenas no momento da atualização da tela, evitando tearing.

No iOS, o pipeline é semelhante: Run Loop processa eventos, Core Animation calcula camadas, Render Server (um processo separado) renderiza e envia o quadro para a GPU. A diferença no iOS é o processo dedicado Render Server, que isola a renderização do aplicativo principal. Se o aplicativo bloquear a thread principal, o Render Server ainda pode desenhar o último quadro conhecido, mas as animações serão interrompidas. Se o próprio Render Server não conseguir acompanhar — a GPU fica ociosa e o Frame Rate cai. De acordo com a Apple WWDC 2022, as causas mais comuns de baixo Frame Rate no iOS são aninhamento excessivo de CALayer, shadowPath pesado e renderização offscreen.

Rastreamento de quadros via Choreographer

O código em Kotlin assina o Choreographer.FrameCallback e registra o tempo real entre os quadros. Se o intervalo exceder 16.6 ms, um quadro perdido é registrado.

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

Taxa de atualização da tela e Frame Rate

Refresh Rate (taxa de atualização) é uma característica de hardware da tela que determina quantas vezes por segundo o display redesenha fisicamente a imagem. Telas padrão têm 60 Hz, flagships modernos têm 90, 120 ou 144 Hz. O Frame Rate do aplicativo pode ser menor, igual ou maior que a taxa de atualização (neste último caso, os quadros excedentes são descartados). O cenário ideal é quando o Frame Rate coincide com o Refresh Rate: cada ciclo de hardware recebe um novo quadro do aplicativo e o movimento é maximamente suave. Se o Frame Rate for menor, a tela repete o último quadro, o que é percebido como micro-engasgos.

Android e iOS suportam a troca dinâmica da taxa de atualização. O Android 12+ usa Smart Refresh Rate: durante a rolagem o sistema eleva a taxa para 120 Hz, em conteúdo estático reduz para 60 Hz para economizar bateria. O iOS ProMotion (iPhone 13 Pro e posteriores) funciona de forma similar — a taxa varia de 10 a 120 Hz dependendo do conteúdo. O desenvolvedor deve verificar se o dispositivo suporta alta taxa e adaptar o orçamento de tempo por quadro. Se o aplicativo não conseguir renderizar um quadro em 8.3 ms (para 120 Hz), é melhor forçar 60 Hz — isso garantirá um Frame Rate estável sem quadros perdidos.

Tipo de telaRefresh RateOrçamento por quadroDispositivos
Padrão60 Hz16.6 msMaioria Android/iOS
Alta90 Hz11.1 msOnePlus, Pixel 6+
Flagship120 Hz8.3 msiPhone Pro, Galaxy S22+
Jogos144 Hz6.9 msROG Phone, Nubia RedMagic

Ferramentas de medição de Frame Rate

Tanto as ferramentas integradas das plataformas quanto os profiladores de terceiros estão disponíveis para medir o Frame Rate em aplicativos móveis. No Android, a ferramenta principal é o GPU Profiling (Developer Options → Profile GPU Rendering), que mostra uma linha do tempo de cada quadro dividida por etapas (Draw, Prepare, Process, Execute). Uma análise mais detalhada é fornecida pelo Android Studio Profiler — ele registra um perfil completo de renderização indicando as Views específicas que causam redesenho. No iOS, utiliza-se Instruments com o template Core Animation — ele mostra FPS, tempo de renderização de camadas e o número de renders offscreen.

Para monitoramento de Frame Rate em produção, utiliza-se Firebase Performance (Android) — ele coleta o Frame Rate em segundo plano e agrega por dispositivo, versão do SO e sessão. No iOS, o MetricKit fornece dados similares através do MXAnimatoryMetric. Para jogos e aplicativos Flutter, utilizam-se FrameTimingCallback (Flutter) e Unity Profiler. É importante medir não o Frame Rate médio, mas os percentis: P50, P90 e P99. Um aplicativo pode mostrar uma média de 55 fps mas ter um P99 de 30 fps — isso significa que 1% do tempo os usuários veem engasgos severos, o suficiente para avaliações negativas.

Medindo Frame Rate no Flutter

O exemplo em Dart mostra como assinar o FrameTimingCallback no Flutter e registrar o número de quadros perdidos. O callback é disparado após cada quadro completo.

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

Otimização da taxa de quadros

A otimização do Frame Rate começa com a identificação de gargalos no pipeline de renderização. Na etapa de Layout, os principais problemas são o aninhamento excessivo da hierarquia de Views, o uso de layouts relativos (RelativeLayout com muitas regras) e chamadas frequentes a requestLayout. A solução é usar ConstraintLayout ou uma hierarquia plana, evitando aninhamentos de mais de 5–6 níveis. Na etapa de Draw — overdraw: quando um pixel é desenhado várias vezes por quadro. Por exemplo, um fundo de Activity branco sob um fragmento semitransparente, sob o qual há mais uma camada — cada pixel é desenhado três vezes. A ferramenta Debug GPU Overdraw mostra as áreas problemáticas com indicação de cores. Recomenda-se manter o overdraw em 2x ou menos.

No iOS, os principais problemas são cornerRadius e masksToBounds pesados — causam renderização offscreen, onde o Core Animation cria um buffer temporário, desenha nele e depois copia o resultado para a tela. A renderização offscreen é facilmente detectada no Instruments Core Animation: se a linha Renderer estiver vermelha — há problemas. A solução é usar UIImageView com imagens pré-cortadas em vez de cornerRadius, evitar groupOpacity e shouldRasterize a menos que seja absolutamente necessário. Para ambas as plataformas, é crítico minimizar o número de chamadas a invalidate() e setNeedsDisplay() — cada uma dessas chamadas dispara um ciclo completo de redesenho da view.

Otimização de hierarquia no Android

O código demonstra a substituição do aninhamento profundo de RelativeLayout por uma estrutura plana com ConstraintLayout. Reduzir o nível de aninhamento de 4 para 1 reduz o tempo de Layout em 30–50%.

kotlin
// Exemplo: estrutura plana 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
        // vinculando dados sem redesenhar o contêiner inteiro
    }
}

Frequências adaptativas e Dynamic Frame Rate

Os aplicativos móveis modernos utilizam cada vez mais o Frame Rate adaptativo — um sistema que ajusta dinamicamente a frequência alvo de acordo com o cenário atual. A rolagem rápida requer 120 fps para suavidade, enquanto uma tela estática precisa apenas de 60 fps ou até 30 fps para vídeo. No Android, a adaptação é implementada através de Choreographer.setFrameInterval (API 33+) e Window.setFrameRate. O desenvolvedor pode especificar uma frequência preferida: setPreferredRefreshRate no SurfaceView ou setFrameRate no Window. O iOS gerencia automaticamente a frequência através do ProMotion, mas o desenvolvedor pode definir explicitamente o preferredFramesPerSecond para o CADisplayLink.

O Dynamic Frame Rate é especialmente importante para jogos e aplicativos com animações. De acordo com o Google, reduzir o Frame Rate de 120 para 60 Hz em uma tela estática economiza até 30–40% de energia da GPU. Para alcançar o melhor equilíbrio entre suavidade e consumo de energia, recomenda-se: medir o Frame Rate real em diferentes cenários, definir os fps alvo dependendo da cena (jogo — 60, menu — 30, vídeo — 24), e alternar os modos através de componentes Lifecycle-aware para que o aplicativo não desperdice recursos renderizando 120 fps em segundo plano quando minimizado.

Definindo o Frame Rate preferido

O código em Swift define preferredFramesPerSecond para o CADisplayLink no iOS. Durante a rolagem a frequência aumenta para 120 Hz, ao parar diminui para 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() {
        // atualização de animação
    }
}

Perguntas frequentes

Qual Frame Rate é considerado bom para um aplicativo móvel?

Para aplicativos móveis, o Frame Rate alvo é de 60 fps (16.6 ms por quadro). Para dispositivos com telas de 120 Hz, é desejável 120 fps. Valores abaixo de 30 fps degradam notavelmente a experiência do usuário.

Como o Frame Rate difere da taxa de atualização da tela?

Frame Rate — quantos quadros por segundo o aplicativo renderiza. Refresh Rate — quantas vezes por segundo a tela atualiza fisicamente a imagem. Quando o Frame Rate é inferior ao Refresh Rate, a tela duplica o último quadro.

Como medir o Frame Rate no Android?

Use GPU Profiling em Developer Options, Android Studio Profiler ou Firebase Performance. Para medição programática — Choreographer.FrameCallback com cálculo do intervalo entre quadros.

O que é overdraw e como ele afeta o Frame Rate?

Overdraw — desenhar um mesmo pixel várias vezes por quadro. Cada camada extra aumenta o tempo da fase Draw e reduz o Frame Rate. O overdraw ótimo é 2x, o crítico é 4x ou mais.

Como o Dynamic Frame Rate economiza bateria?

Em conteúdo estático, o Dynamic Frame Rate reduz a frequência para 30–60 Hz, diminuindo a carga da GPU em 30–40%. Durante a rolagem, a frequência aumenta para 90–120 Hz para suavidade.

Resumo

  • Frame Rate — número de quadros por segundo que determina a suavidade da interface e animações.
  • Frame Rate alvo — 60 fps (16.6 ms por quadro) para telas padrão, 120 fps (8.3 ms) para alta taxa de atualização.
  • Quadros perdidos causam Jank — engasgos visíveis que degradam a experiência do usuário.
  • Principais causas de baixo Frame Rate — aninhamento excessivo de Views, overdraw e renderização offscreen.
  • Choreographer (Android) e CADisplayLink (iOS) sincronizam a renderização com VSync.
  • Frame Rate adaptativo equilibra suavidade e consumo de energia, reduzindo a carga da GPU em até 40%.
  • Perfilar o Frame Rate é o primeiro passo para otimizar o desempenho de um aplicativo móvel.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também