Mobile

Performance em React Native: FlatList, imagens e re-render em apps corporativos

Guia pratico para melhorar listas, imagens e re-render em apps React Native corporativos com FlatList, memoizacao, paginacao, cache e testes em release.

Guia de leitura

O que esta leitura cobre

Use os pontos abaixo como mapa para navegar pelo artigo, comparar sintomas, riscos e proximos passos antes de aplicar qualquer decisao tecnica.

  1. 011. Comece pelo sintoma, nao pela supersticao
  2. 022. Entenda o que o usuario sente como performance
  3. 033. Nunca confie so no modo dev
  4. 044. Trate a lista como produto, nao como detalhe visual
  5. 055. Use `FlatList` com criterio, nao no padrao cru

Em app corporativo, problema de performance quase nunca aparece como uma metrica abstrata. Ele aparece como usuario reclamando que a lista trava, o scroll engasga, a tela demora para abrir, a imagem pisca, o botao responde atrasado ou o celular esquenta depois de alguns minutos de uso. Em projetos React Native, esses sintomas costumam nascer da combinacao entre lista grande, payload exagerado, imagem pesada, estado mal distribuido e testes feitos apenas em modo de desenvolvimento.

Esse tipo de gargalo importa ainda mais em produtos como o app do PraxyManager, porque o aplicativo nao vive em laboratorio. Ele roda em aparelho intermediario, com internet instavel, alternando entre outras aplicacoes, com dados vindos de API e expectativa de resposta rapida em tarefas operacionais.

Este guia organiza um caminho pratico para melhorar desempenho em telas React Native que exibem listas, cards, miniaturas, filtros e atualizacao de dados. O foco nao e perseguir benchmark bonito. O foco e deixar o app confiavel e fluido para quem trabalha com ele.

1. Comece pelo sintoma, nao pela supersticao

Antes de trocar biblioteca ou sair adicionando memoizacao em todo componente, descreva o sintoma real.

Perguntas uteis:

  • A lentidao acontece ao abrir a tela ou ao rolar a lista?
  • O problema aparece em qualquer aparelho ou so em aparelhos medianos?
  • O gargalo ocorre com dados reais ou apenas quando a base cresce?
  • O scroll trava por causa da lista, da imagem ou da chamada da API?
  • A tela piora quando o usuario aplica filtro, busca ou abre detalhes?
  • O problema some quando a internet esta boa?

Um app que parece lento pode estar sofrendo por motivos bem diferentes: renderizacao excessiva, imagens enormes, resposta lenta da API, serializacao de objetos grandes, transicao entre telas com trabalho pesado na thread JavaScript ou lista montada sem virtualizacao suficiente.

2. Entenda o que o usuario sente como performance

A documentacao oficial do React Native trata performance como a capacidade de manter a interface responsiva e visualmente fluida, sem travar animacoes, toques ou scroll. Em termos praticos, o usuario sente problema quando a tela perde frame, demora para reagir ao toque ou mostra conteudo em blocos atrasados durante a rolagem.

Em app corporativo, os sintomas mais comuns sao:

  • lista com salto ou branco entre blocos ao rolar;
  • toque que demora para abrir detalhe;
  • campo de busca que trava enquanto digita;
  • imagens que chegam tarde demais;
  • cabecalho, abas ou contadores atualizando toda a tela sem necessidade;
  • scroll bom em simulador, mas ruim em aparelho real;
  • tela fluida no inicio e degradando com o tempo.

Nomear o sintoma ajuda a escolher a intervencao certa. Performance boa nao e apenas FPS alto em um grafico. E sensacao de controle, leitura e resposta.

3. Nunca confie so no modo dev

React Native em modo de desenvolvimento carrega validacoes extras, logs, ferramentas e comportamentos que nao representam a experiencia final. Um fluxo que parece pesado no modo dev pode ficar aceitavel em release. O inverso tambem acontece: a tela parece boa em dev com poucos dados, mas engasga em release quando recebe volume real e imagens reais.

Por isso, uma regra pratica e obrigatoria:

  • teste listas pesadas em build de release ou preview;
  • use o fluxo de development build e EAS Build quando o projeto depende de recursos nativos e validacao real;
  • meca em aparelho fisico, nao apenas no emulador;
  • repita teste com base de dados maior que a minima usada no desenvolvimento.

O artigo React Native para app corporativo ja defendia isso: o primeiro release precisa ser confiavel, e confianca depende de validar o comportamento do app em condicoes proximas do uso real.

4. Trate a lista como produto, nao como detalhe visual

Grande parte da percepcao de performance em app corporativo vem da tela de listagem: pedidos, tarefas, chamados, indicadores, atendimentos, historico ou itens pendentes. Se a lista nao responde bem, o usuario sente que o app inteiro e ruim.

Antes de otimizar `FlatList`, responda:

  • o usuario realmente precisa carregar todos os itens de uma vez?
  • cada card mostra informacao essencial ou excesso de detalhe?
  • ha miniaturas que poderiam ser menores?
  • o item da lista tem altura previsivel?
  • o scroll infinito esta bem controlado?
  • a tela depende de duas ou tres chamadas paralelas que poderiam ser reorganizadas?

Muitas vezes a melhor otimizacao nao esta no componente da lista, mas na decisao de produto: menos informacao por item, mais paginacao, imagem menor, filtro antes da consulta, detalhe sob demanda.

5. Use `FlatList` com criterio, nao no padrao cru

`FlatList` e a base natural para listas grandes no React Native porque renderiza de forma virtualizada. Mas o ganho real depende da configuracao. A documentacao oficial mostra que propriedades como `initialNumToRender`, `maxToRenderPerBatch`, `updateCellsBatchingPeriod`, `windowSize` e `removeClippedSubviews` mudam a troca entre memoria, responsividade e risco de areas em branco.

Um ponto de partida saudavel:

  • `keyExtractor` com identificador estavel do item;
  • `renderItem` estavel, evitando recriacao desnecessaria a cada render;
  • componentes de item leves e previsiveis;
  • `initialNumToRender` suficiente para preencher a primeira dobra do aparelho real;
  • `windowSize` ajustado quando a lista e muito longa;
  • `onEndReached` usado com paginacao de verdade, nao para carregar centenas de itens sem controle.

Quando a altura do item e conhecida ou muito previsivel, `getItemLayout` ajuda a evitar calculos extras no scroll e melhora a navegacao para indices mais distantes. Se a altura varia demais, esse atalho pode mais atrapalhar do que ajudar.

6. Parametros de `FlatList` sao troca, nao receita magica

Vale entender o custo de cada parametro principal:

  • `initialNumToRender`: se ficar baixo demais, a tela abre com lacunas; se ficar alto demais, a montagem inicial pesa.
  • `maxToRenderPerBatch`: lotes maiores reduzem risco de branco no scroll, mas podem travar mais a resposta ao toque.
  • `updateCellsBatchingPeriod`: controla a frequencia desses lotes; muito agressivo pode deixar scroll bonito e toque ruim.
  • `windowSize`: janela maior deixa mais itens prontos, mas aumenta uso de memoria.
  • `removeClippedSubviews`: pode ajudar fora da area visivel, mas merece cautela em telas com transformacoes, posicionamento absoluto ou comportamento estranho no iOS.

O ajuste certo depende do tipo de lista. Uma lista de aprovacoes com item simples aceita configuracao diferente de uma timeline com imagem, status, botoes, badge e subtabela.

7. O item da lista precisa ser barato para renderizar

Nao adianta configurar `FlatList` se cada item carrega logica pesada. Em app corporativo, isso acontece quando o card faz formatacao cara, calcula dados derivados, monta muitos componentes condicionais, executa hooks custosos ou recebe props novas a cada scroll.

Boas praticas:

  • manter o item focado em apresentar dados ja preparados;
  • evitar criar objetos e funcoes inline em excesso;
  • memorizar o card quando as props realmente sao estaveis;
  • deixar calculos repetitivos fora do componente do item;
  • usar campos prontos da API quando a montagem local ficou cara demais.

Memoizacao ajuda quando existe repeticao de render sem mudanca real. Ela nao corrige dado ruim, estrutura ruim nem efeito colateral escondido.

8. Re-render global costuma custar mais do que a equipe imagina

Uma causa frequente de engasgo e atualizar estado alto demais na arvore. O usuario digita no filtro, abre um dropdown ou troca uma preferencia, e metade da tela renderiza novamente.

Observe com cuidado:

  • estado de busca fica perto da lista ou no topo da pagina inteira?
  • cada mudanca de loading recria cabecalhos, tabs e cards juntos?
  • o contexto global esta mudando para resolver detalhe local?
  • o seletor de estado entrega objeto novo a cada render?
  • o hook de dados traz array novo sem necessidade?

Em telas grandes, separar estado de interface, estado de servidor e estado de item selecionado costuma reduzir bastante o re-render desnecessario. O problema nao e usar estado global; o problema e usalo para tudo.

9. Imagem pesada destroi scroll mais rapido que muita regra de negocio

Em muitos apps, a lista ate esta bem montada, mas cada item carrega imagem grande, miniatura sem compressao, avatar de URL externa lenta ou placeholder inexistente. O resultado e uma tela que rola pior e parece instavel.

Checklist para imagens:

  • usar miniaturas no tamanho que a tela realmente precisa;
  • evitar baixar imagem de alta resolucao para exibir em card pequeno;
  • definir largura e altura previsiveis para evitar salto visual;
  • usar placeholder, fundo ou skeleton para o carregamento nao parecer falha;
  • evitar varias imagens ao mesmo tempo na primeira dobra sem necessidade;
  • reaproveitar cache quando a mesma imagem aparece em mais de uma tela.

Se o projeto usa Expo, vale avaliar `expo-image` para placeholders, cache e transicao mais previsivel. Isso nao substitui miniatura correta nem payload enxuto, mas ajuda a estabilizar a experiencia visual.

10. API e paginacao fazem parte da performance mobile

Lista lenta nem sempre e culpa da UI. Muitas vezes a API manda campos demais, sem pagina, sem filtro, com relacionamentos desnecessarios ou com imagem completa embutida em resposta que deveria ser leve.

Para telas mobile, a conversa com o backend precisa ser desenhada para uso real:

  • retornar somente campos usados na lista;
  • paginacao consistente;
  • ordenacao previsivel;
  • filtros que evitam baixar tudo para filtrar no aparelho;
  • miniatura separada da imagem detalhada;
  • status e contadores precomputados quando isso reduz custo de tela.

Se a equipe esta carregando 500 itens para exibir 12 na dobra, a otimizacao certa pode estar mais perto do hub de APIs do que do componente visual. O guia API Spring Boot lenta: como investigar ajuda a ler esse lado do problema.

11. Busca, filtro e ordenacao precisam ser desenhados para aparelho real

Outro erro comum e fazer o app recalcular toda a lista a cada tecla. Em aparelho bom isso passa despercebido. Em aparelho comum, vira travamento.

Algumas estrategias simples ajudam:

  • debounce na busca quando ela dispara consulta remota;
  • aplicar filtro local apenas sobre conjuntos pequenos ou ja reduzidos;
  • nao recalcular contadores e agrupamentos pesados a cada caractere;
  • mover trabalho caro para o backend quando a operacao depende de muitos dados;
  • mostrar estado de carregamento claro em vez de travar a tela inteira.

Filtro responsivo nao e apenas rapidez absoluta. E deixar claro quando a aplicacao esta buscando, quando terminou e o que mudou na lista.

12. Cuidado com efeitos colaterais escondidos no scroll

Algumas telas pioram porque cada item dispara efeito quando entra em tela: analytics, leitura de storage, calculo de data, formatacao, medicao de layout, avatar, badge, icone remoto, permissao ou observador extra. Um item isolado parece barato, mas 20 itens juntos deixam o scroll pesado.

Revise com honestidade:

  • o card precisa mesmo disparar efeito ao montar?
  • esse efeito pode acontecer uma vez no pai?
  • o valor pode ser preparado antes da renderizacao?
  • ha leitura repetida de storage, contexto ou rede?
  • o evento de analytics esta em lugar certo?

Scroll fluido pede item previsivel. Tudo o que nao precisa nascer junto com o card deve sair do caminho dele.

13. Meca em cenarios reais de uso

Uma tela so pode ser considerada boa depois de passar por cenarios proximos do usuario:

  1. lista curta e lista grande;
  2. Wi-Fi bom e rede movel ruim;
  3. aparelho intermediario e aparelho mais forte;
  4. app aberto do zero e app retornando do segundo plano;
  5. filtro rapido, scroll longo e abertura de detalhe;
  6. imagem carregando com e sem cache.

Tambem vale registrar sinais minimos em analytics e monitoramento: tempo para primeira lista util, erro de consulta, tamanho medio de payload, pagina mais acessada, taxa de nova carga e versao do app. Isso conecta performance percebida com evidencias. A pagina de indicadores tecnicos ajuda a transformar esse acompanhamento em rotina.

14. Um roteiro pratico para atacar a tela lenta

Se a tela de listagem esta ruim hoje, um roteiro objetivo costuma funcionar melhor que otimizacao aleatoria:

  1. Reproduzir o problema em aparelho real e build de release.
  2. Identificar se o gargalo aparece na carga inicial, no scroll, no filtro ou na abertura de detalhe.
  3. Reduzir o payload da API para o minimo da lista.
  4. Garantir paginacao ou scroll incremental real.
  5. Revisar `FlatList` com `keyExtractor`, item leve e parametros basicos.
  6. Separar estado local para evitar re-render global.
  7. Trocar imagem pesada por miniatura adequada e placeholder previsivel.
  8. Medir novamente no mesmo aparelho e no mesmo cenario.

Essa sequencia evita dois extremos ruins: sair micro-otimizando sem prova e culpar apenas o backend sem olhar a UI.

15. Erros comuns

  • carregar tudo e confiar que o virtualizado resolve sozinho;
  • testar lista pesada apenas em modo dev;
  • usar imagem grande em card pequeno;
  • fazer filtro local em array enorme a cada tecla;
  • memorizar componente sem estabilizar props;
  • colocar loading, busca e lista inteira sob o mesmo estado alto;
  • misturar detalhe demais no card principal;
  • otimizar `FlatList` sem rever payload da API;
  • considerar simulador como verdade de performance.

16. Quando o problema merece diagnostico tecnico

Se a equipe ja reduziu payload, ajustou a lista, revisou imagens e ainda encontra tela travando, talvez o problema esteja espalhado entre app, API, contrato de dados, cache, estado, analytics e infraestrutura. Nesses casos, o melhor caminho e juntar evidencia antes de trocar mais codigo no escuro.

Vale procurar apoio quando:

  • a lista continua ruim mesmo com poucos itens;
  • o problema aparece so em producao;
  • o backend responde bem, mas a tela continua instavel;
  • ha duvida se o gargalo esta na UI, na API ou no modelo de dados;
  • o time precisa preparar o app para crescimento real de uso.

O hub Mobile e React Native organiza os artigos dessa trilha, e o diagnostico tecnico pode ajudar quando a investigacao precisa cruzar app, API e arquitetura.

Performance em React Native nao melhora com truque isolado. Ela melhora quando lista, imagem, estado e API passam a trabalhar a favor da mesma tarefa. Em app corporativo, isso significa menos atrito na operacao e mais confianca para expandir o mobile sem transformar cada tela em uma aposta.

Referencias editoriais: React Native Performance Overview, Optimizing FlatList Configuration, FlatList, React Native Images, Expo Image e Expo development builds.

Glossario conectado

Termos tecnicos desta leitura

Alguns conceitos aparecem com frequencia neste tema. Abrir o glossario ajuda a comparar definicoes, exemplos e leituras relacionadas sem sair do contexto do artigo.

MobileFlatListComponente do React Native para renderizar listas virtualizadas, importante para desempenho em telas com muitos itens.MobileMemoizacaoTecnica para reaproveitar resultado ou renderizacao quando entradas relevantes nao mudaram, reduzindo trabalho repetido.MobileReact NativeFramework para criar aplicativos nativos para Android e iOS usando React, componentes nativos e JavaScript ou TypeScript.MobilePrefetch de imagemCarregamento antecipado de imagens para reduzir atraso visual quando a tela ou item for exibido ao usuario.MobileVirtualizedListBase de virtualizacao de listas no React Native, usada para renderizar apenas parte dos itens visiveis e proximos da tela.APIsAPIInterface que permite que sistemas conversem por contratos definidos, normalmente usando requisicoes HTTP.
Continue a análise

Próximos passos para aprofundar o tema.

Veja conteúdos próximos e materiais práticos para transformar a leitura em uma revisão mais objetiva.

Mobile

Contrato de API para app React Native: Spring Boot sem retrabalho no mobile

Guia pratico para desenhar APIs Spring Boot que funcionam bem com apps React Native, cobrindo erros, paginacao, retry, idempotencia e versao.

Ler artigo
Mobile

Seguranca em app React Native corporativo: tokens, dados sensiveis e API

Guia pratico para proteger tokens, dados locais, logs, deep links e chamadas de API em apps corporativos React Native.

Ler artigo
Mobile

Navegacao autenticada no app React Native: rotas por perfil sem bagunca

Guia pratico para organizar login, sessao, rotas protegidas, perfil de acesso e deep links em apps corporativos React Native.

Ler artigo

Converse sobre seu cenário técnico.

Envie sua dúvida ou contexto para avaliarmos o melhor caminho.

Prefere falar direto?

Tambem atendemos pelo WhatsApp em (12) 98855-9188.

Falar no WhatsApp

Ao enviar, você concorda que a RM Porto Tech utilize seus dados para responder ao contato solicitado.

WhatsApp(12) 98855-9188