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:
- lista curta e lista grande;
- Wi-Fi bom e rede movel ruim;
- aparelho intermediario e aparelho mais forte;
- app aberto do zero e app retornando do segundo plano;
- filtro rapido, scroll longo e abertura de detalhe;
- 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:
- Reproduzir o problema em aparelho real e build de release.
- Identificar se o gargalo aparece na carga inicial, no scroll, no filtro ou na abertura de detalhe.
- Reduzir o payload da API para o minimo da lista.
- Garantir paginacao ou scroll incremental real.
- Revisar `FlatList` com `keyExtractor`, item leve e parametros basicos.
- Separar estado local para evitar re-render global.
- Trocar imagem pesada por miniatura adequada e placeholder previsivel.
- 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.
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.