Meça antes de otimizar: um loop simples — baseline, perfilagem, mude uma coisa, verifique o impacto — e construa o hábito tranquilo de trabalhar com performance.

O trabalho de performance parece aleatório quando você começa por consertos. Um dia você minifica arquivos, no outro ajusta cache, depois remove uma biblioteca. Às vezes isso ajuda. Às vezes nada muda, e você não sabe por quê.
O maior risco é otimizar a coisa errada. Se a página está lenta porque o main thread está bloqueado por JavaScript, passar horas comprimindo imagens pode mal mover a agulha. Ou você pode acelerar algo que os usuários não percebem, enquanto o atraso real é uma chamada de API longa, um layout que fica recalculando, ou um único script bloqueante.
Também há uma armadilha em julgar pela sensação. “Parece mais rápido” pode vir de mudanças placebo (como um spinner) ou de testar em outra rede, dispositivo ou horário. “É mais rápido” significa que a mesma ação, sob as mesmas condições, produziu números melhores.
Uma promessa simples resolve a maior parte disso: meça antes de otimizar, e então decida. Quando você trata performance como um problema de medição, para de adivinhar e começa a aprender.
Um loop prático fica assim: escolha uma ação de usuário para melhorar, registre uma baseline em condições repetíveis, faça uma mudança que você consiga explicar, então re-meça e mantenha a mudança apenas se os números melhorarem.
Paul Irish é uma das vozes mais conhecidas em performance web. Pelo seu trabalho em ferramentas de navegador e orientações de performance, ele ajudou a popularizar uma ideia direta: seu primeiro trabalho não é supor o que está lento, é provar isso.
Essa mentalidade muda a dinâmica do time. Em vez de argumentar por hábitos como “imagens são sempre o problema” ou “deve ser o framework”, você começa com evidências. Quando dá para apontar uma timeline, uma query lenta ou uma long task, a conversa muda de culpa para correções.
“Medir antes de otimizar” também acalma debates porque cria regras compartilhadas: concorde sobre o que está medindo, concorde sobre o que significa “melhor”, e só comemore quando os números mudarem.
Isso funciona em sites pequenos e apps gigantes. Uma única baseline pode parar micro-otimizações aleatórias em uma página de marketing. Em um produto grande, medições consistentes evitam que performance vire uma lista de tarefas sem fim.
Uma forma simples de tornar isso real é tratar performance como um relatório de bug: passos claros para reproduzir, a métrica que você viu e uma mudança ligada a um resultado. Se duas pessoas discordarem, reexecute a medição e deixe os dados decidirem.
Trate performance primeiro como um problema de instrumentação: adicione formas de observar o que os usuários realmente experimentam. Se você não consegue ver, vai acabar debatendo opiniões, não evidências. Esse é o sentido real por trás de medir primeiro.
Instrumentação não precisa ser sofisticada. É coletar alguns sinais de forma consistente, nos mesmos lugares, para responder perguntas básicas:
Normalmente você quer dois tipos de dados.
Dados de laboratório são capturados em um setup controlado: um laptop ou dispositivo de teste específico, um perfil de rede estável, os mesmos passos a cada execução. É ótimo para depurar porque você pode reproduzir o problema sob demanda.
Dados reais de usuário são o que as pessoas experimentam no mundo real: dispositivos, locais e qualidade de conexão diferentes. É ótimo para priorizar porque mostra o que realmente prejudica usuários, não só um teste isolado.
Mesmo sem ser especialista, você pode medir marcos de carregamento (como o primeiro conteúdo exibido), long tasks e bloqueio do main-thread, requisições de rede lentas, trabalho de renderização caro (layout, style, paint) e tempo de resposta do servidor.
Esses sinais normalmente aparecem em alguns lugares: DevTools do navegador para perfilagem em laboratório, logs e traces do servidor para tempos de backend, e dashboards de analytics ou RUM para dados reais. Por exemplo, se o checkout parece lento, o DevTools pode mostrar que o navegador está ocupado renderizando uma UI de carrinho enorme enquanto os logs do servidor mostram que a API está rápida. Sem instrumentação, você pode otimizar o backend e nunca resolver o problema real.
Para medir antes de otimizar, você precisa de um ponto de partida confiável. Uma baseline é a mesma ação, medida da mesma forma, nas mesmas condições.
Comece com uma jornada real de usuário, não “o site inteiro”. Escolha algo que você consiga descrever numa frase, como “abrir a página inicial e rolar até o primeiro grid de produtos” ou “fazer login e ir ao dashboard”. Manter estreito torna os números mais estáveis e os próximos passos mais claros.
Depois, escolha de 1 a 3 métricas que combinem com a jornada. Para uma visualização de página, um par comum é LCP (velocidade do conteúdo principal) e TTFB (tempo de resposta do servidor). Para um fluxo como checkout, você pode rastrear o tempo para completar a etapa 1 e o tempo de resposta da chamada de pagamento. Muitas métricas facilita a seleção tendenciosa.
Anote a configuração do teste para que outra pessoa possa reproduzir depois. Pequenas diferenças podem alterar resultados:
Finalmente, defina “bom o suficiente” para seu público. Por exemplo: “LCP abaixo de 2,5s em um celular mid-range em 4G.” Se você usa Koder.ai, tirar um snapshot antes dos testes ajuda a manter sua baseline ligada a uma versão conhecida.
Antes de perfilar qualquer coisa, faça o problema acontecer de novo sob demanda. Se você não consegue repeti-lo, não pode confiar no resultado.
Comece pelo que as pessoas sentem, não pelo que você supõe. É um primeiro render lento? Um clique que fica travado antes de mudar algo? Uma espera longa após submeter um formulário? Escolha o momento que os usuários reclamam e foque nele.
Faça uma execução rápida para confirmar que a lentidão é real e repetível. Mantenha todo o resto igual: mesma página, mesmo dispositivo, mesma rede se possível. Então anote o gatilho e o momento exato que parece lento, como “após clicar em Pagar, o botão congela por um segundo” ou “o scroll engasga quando a lista de produtos aparece”.
Uma maneira simples de manter repetibilidade é um script pequeno: abra a página em uma aba nova, faça a ação que dá lag, note o ponto exato em que desacelera, e repita uma vez para confirmar.
Capture uma ou duas gravações de baseline, não dezenas. Você quer evidência suficiente para dizer: “Sim, a lentidão acontece, e acontece bem aqui.”
Quando você conseguir reproduzir a lentidão, pare de adivinhar. Abra um profiler (para a maioria, o painel Performance do navegador) e grave uma execução da interação lenta. O objetivo não é achar todo problema. É entender para onde o tempo vai.
Comece pelos maiores blocos de tempo. Picos pequenos podem ser reais, mas raramente explicam um atraso perceptível sozinhos.
Uma forma útil de ler uma gravação é agrupar o tempo em alguns baldes: rede e carregamento (espera por requisições), scripting no main thread (long tasks de JavaScript), renderização e paint (layout e style), gaps de idle (esperando outra coisa), e trabalho repetido (o mesmo passo caro acontecendo várias vezes).
Um erro comum é confundir resposta lenta do servidor com trabalho lento no cliente. Se a timeline mostra longos gaps com requests em voo, o gargalo pode ser rede ou backend. Se mostra longas tasks no main thread, você tem um problema no front end mesmo com a rede rápida.
Antes de mudar qualquer coisa, escreva uma hipótese curta e testável baseada no que viu. Por exemplo: “A página parece lenta porque o main thread é bloqueado pelo parsing de JSON logo após a resposta da API.” Essa frase prepara o próximo passo.
Depois de identificar o provável gargalo, resista ao impulso de “consertar tudo”. Mude uma variável para poder conectar causa e efeito.
Mantenha a mudança pequena e fácil de reverter. Rewrites grandes embaralham o resultado: se a performance melhorar, você não vai saber por quê. Se piorar, o rollback fica arriscado.
Boas mudanças de “uma coisa” são específicas e testáveis. Exemplos: adiar ou remover um script de terceiros que bloqueia a renderização, comprimir uma imagem grande na página lenta, adicionar cache a uma query de banco cara, dividir um componente pesado para renderizar menos trabalho inicial, ou reduzir trabalho em um loop quente que você viu no profiler.
Antes de tocar no código, escreva o que mudou, por que escolheu isso e o que espera melhorar (por exemplo, “reduzir tempo no main-thread” ou “cortar o tempo do DB pela metade”).
Se seu time usa uma plataforma com snapshots e rollback (como Koder.ai), tire um snapshot antes da mudança para que “pequeno e reversível” seja real, não aspiracional.
Você mudou uma coisa. Agora prove que ajudou.
Reexecute exatamente o mesmo setup que usou na baseline: mesmo dispositivo, mesma versão do navegador, mesma rota e fluxo, e o mesmo número de runs. Compare antes vs depois usando as mesmas métricas. Não adicione métricas no meio do caminho só porque elas parecem melhores.
Ruído é a razão mais comum de brigas sobre performance. Fique atento a cache quente vs frio, extensões ou processos de background, condições de rede diferentes ou VPN, variância do servidor (minuto tranquilo vs minuto ocupado), e a diferença entre “logo após o deploy” e estado estável.
Se a mediana melhora mas o pior caso piora, isso é um tradeoff real. Decida o que importa para seus usuários, então documente a decisão: manter a mudança, reverter, ou escrever uma nova hipótese e testar de novo.
Trabalhar com performance fica confuso quando você mede a coisa errada ou muda várias coisas de uma vez. Dá para gastar muito esforço sem uma vitória clara, mesmo que seu app esteja melhorando.
Um erro comum é tratar uma única nota/score como objetivo. Scores podem ser úteis, mas usuários não experimentam “um 92”. Eles experimentam “a página mostra conteúdo em 2 segundos” ou “tocar em Comprar responde imediatamente”. Escolha um resultado visível ao usuário e meça de forma consistente.
Outra armadilha é testar só em um laptop potente. Muitas lentidões aparecem em celulares mid-range, redes instáveis, ou quando a CPU está ocupada. Se você só perfilar no melhor dispositivo que tem, pode perder o gargalo.
A confusão normalmente vem de padrões como melhorar o que é mais fácil ao invés do que consome mais tempo, agrupar vários ajustes numa mudança só, alternar caminhos de teste a cada execução, pular um re-teste porque “parece mais rápido”, ou declarar vitória sem reexecutar a mesma baseline.
Se você está construindo o app com uma plataforma guiada por chat como o Koder.ai, a mesma disciplina vale: uma mudança, depois verifique no mesmo fluxo exato para confiar no resultado.
Se for manter um hábito, mantenha este: medir antes de otimizar. O objetivo não é dados infinitos. É um loop repetível em que você pode confiar.
Nomeie a jornada exata do usuário que importa. “Homepage está lenta” é vago. “Do product page ao clique em Comprar até ver a confirmação” te dá um caminho de cliques que você pode repetir.
Use este checklist:
A versão calma do trabalho de performance é simples: um caminho, um setup, uma mudança, um resultado verificado.
Uma reclamação comum: o checkout parece lento logo após o cliente clicar em “Pagar”. As pessoas começam a chutar (imagens, fontes, o botão). Em vez disso, trate como um teste que você pode repetir.
Defina uma baseline que você possa rodar novamente. Escolha um dispositivo e um caminho (carrinho → checkout → Pagar → confirmação). Ative throttling de rede (por exemplo, Fast 3G) e mantenha igual em cada execução. Meça um número simples: tempo do clique em “Pagar” até ver a tela de confirmação.
Então profile esse mesmo momento e veja para onde o tempo vai. Normalmente você decide entre três baldes: rede (uma request longa ou muitas requests), servidor (a chamada de pagamento é lenta enquanto o navegador está ocioso), ou main thread (o navegador está ocupado rodando JavaScript e não atualiza a UI).
Imagine que o profile mostra que ao clicar em “Pagar” o navegador dispara uma request de analytics e um script de verificação antifraude, e a request de pagamento fica atrás delas. Isso não é um problema de “tornar tudo mais rápido”. É um passo bloqueante.
Faça uma mudança de uma coisa por vez. Por exemplo, permita que a request de pagamento inicie imediatamente e envie analytics só após a tela de confirmação ser exibida.
Verifique com o mesmo setup: mesmo throttling, mesmos passos, múltiplas runs. Se o tempo até a confirmação cair e os erros não aumentarem, você teve um ganho real. Também cheque rapidamente que não quebrou reembolsos, retries ou proteção contra duplo envio.
Performance se mantém sã quando vira rotina, não missão de resgate. Faça da medição a ação padrão, mesmo quando tudo parece bem.
Escolha um pequeno conjunto de métricas que seu time sempre acompanhará. Mantenha consistente para que tendências sejam fáceis de identificar:
Construa um loop em torno dessas métricas. Uma verificação semanal da baseline costuma ser suficiente. Quando uma métrica deriva, esse é o gatilho para reproduzir a lentidão, perfilá-la, fazer uma mudança e verificar o impacto.
Mantenha um log simples de performance no formato que seu time realmente use. Registre o que mediu (incluindo dispositivo, rede e build), o que mudou e o que os números fizeram depois.
Se você constrói com Koder.ai, o Modo de Planejamento pode ajudar a escrever a jornada do usuário e a métrica que importa antes de mudar qualquer coisa. Então use snapshots e rollback para manter experimentos seguros: snapshot, aplique uma mudança, re-teste e reverta se o resultado for ruidoso ou pior.
Em planejamento ou revisão, uma pergunta mantém a cultura saudável: “O que medimos, e o que isso mudou?”
Porque você pode facilmente gastar horas melhorando algo que não está causando a lentidão. Comece provando para onde o tempo vai (rede, servidor, main thread, renderização) e então foque no gargalo maior.
Escreva uma ação específica e as condições exatas, então repita:
Se você não consegue repetir, não dá pra confiar no resultado.
Escolha 1–3 métricas que correspondam ao que os usuários percebem:
Dados de laboratório são controlados e repetíveis (ótimos para depurar). Dados reais de usuários mostram dispositivos e redes reais (ótimos para priorizar).
Um bom padrão: use dados reais para encontrar as piores jornadas e depois use perfilagem em laboratório para explicar por que estão lentas e testar correções com segurança.
Trate como um bug report:
Isso desloca a conversa de opiniões (“devem ser as imagens”) para evidências.
Grave a interação lenta em um profiler e procure o maior bloco de tempo:
Depois escreva uma hipótese de uma frase que você possa testar.
Mantém causa e efeito claros. Se você muda cinco coisas e a página fica mais rápida, não vai saber qual mudança foi responsável. Se piorar, reverter vira bagunça.
Regra prática: uma mudança que você consegue explicar, uma métrica que espera melhorar, e então re-medir.
Faça o mesmo setup de teste e compare antes/depois usando as mesmas métricas.
Para reduzir ruído:
Mantenha a mudança só se os números melhorarem nas mesmas condições.
Erros comuns:
Mantenha uma jornada, um setup e um resultado verificado.
Use-os para tornar experimentos seguros e comparáveis:
As ferramentas ajudam, mas a vitória real é o loop repetível: baseline → profile → uma mudança → verificar.
Evite rastrear muitos números ao mesmo tempo para não correr o risco de cherry-pick.