Orçamentos de desempenho ajudam a manter apps web rápidos definindo limites claros para tempo de carregamento, tamanho de JS e Core Web Vitals, além de auditorias rápidas e regras de reparar primeiro.

Um orçamento de desempenho é um conjunto de limites acordados antes de construir. Pode ser um limite de tempo (quão rápida a página parece), um limite de tamanho (quanto código você envia) ou um teto simples (requisições, imagens, scripts de terceiros). Se você ultrapassar o limite, trata-se como um requisito quebrado, não como uma tarefa “boa de consertar depois”.
A velocidade normalmente piora porque o envio é aditivo. Cada novo widget adiciona JavaScript, CSS, fontes, imagens, chamadas de API e mais trabalho para o navegador. Mesmo mudanças pequenas se acumulam até o app ficar pesado, especialmente em celulares de gama média e redes mais lentas — onde está a maioria dos usuários reais.
Opiniões não protegem você aqui. Uma pessoa diz “está ok no meu laptop”, outra diz “está lento”, e o time debate. Um orçamento encerra o debate ao transformar desempenho em uma restrição de produto que você pode medir e aplicar.
É aqui que o pensamento do Addy Osmani se encaixa: trate desempenho como restrições de design e regras de segurança. Você não “tenta” manter a segurança ou “espera” que o layout pareça bom. Você define padrões, verifica continuamente e bloqueia mudanças que os quebram.
Orçamentos resolvem vários problemas práticos ao mesmo tempo. Tornam trade-offs explícitos (adicionar uma feature significa pagar por isso em outro lugar), pegam regressões cedo (quando corrigir é mais barato) e dão a todos a mesma definição de “rápido o suficiente”. Também reduzem o pânico de última hora que tende a aparecer antes de um lançamento.
Aqui está o tipo de cenário para o qual orçamentos são feitos: você adiciona uma biblioteca rica de gráficos para uma visualização de dashboard. Ela é enviada para todos, aumenta o bundle principal e atrasa a primeira tela significativa. Sem um orçamento, isso passa porque a feature “funciona”. Com um orçamento, o time precisa escolher: lazy-load do gráfico, trocar a biblioteca ou simplificar a visualização.
Isso importa ainda mais quando times conseguem gerar e iterar apps rapidamente, inclusive com fluxos de build orientados por chat como o Koder.ai. Velocidade é ótima, mas também facilita enviar dependências extras e floreios de UI sem perceber. Orçamentos impedem que iterações rápidas se transformem em produtos lentos.
O trabalho de desempenho falha quando você mede tudo e não é responsável por nada. Escolha uma jornada de página que importe para usuários reais e trate-a como âncora para seus orçamentos.
Um bom ponto de partida é uma jornada principal onde velocidade afeta conversão ou trabalho diário, como “home até cadastro”, “primeiro carregamento do dashboard após login” ou “checkout e confirmação de pagamento”. Escolha algo representativo e frequente, não um caso de borda.
Seu app não roda no seu laptop. Um orçamento que parece bom numa máquina rápida pode ser lento num celular de gama média.
Decida uma classe de dispositivo alvo e um perfil de rede para começar. Mantenha simples e escreva como uma frase que todo mundo possa repetir.
Por exemplo: um celular Android de gama média dos últimos 2–3 anos, em 4G em movimento (não Wi‑Fi do escritório), medindo uma carga fria e depois uma navegação chave, na mesma região onde está a maioria dos usuários.
Isso não é escolher o pior caso. É escolher um caso comum que você realmente possa otimizar.
Números só importam se forem comparáveis. Se uma execução é “Chrome com extensões num MacBook” e a próxima é “mobile com throttling”, sua linha de tendência vira ruído.
Escolha um ambiente base e mantenha-o para as checagens do orçamento: mesma versão do navegador, mesmas configurações de throttling, mesmo caminho de teste e mesmo estado de cache (frio ou quente). Se usar dispositivos reais, use o mesmo modelo.
Agora defina o que “rápido o suficiente” significa em termos de comportamento, não de demos perfeitas. Por exemplo: “os usuários conseguem começar a ler o conteúdo rapidamente” ou “o dashboard parece responsivo após o login”. Traduza isso em uma ou duas métricas para essa jornada e então defina orçamentos ao redor delas.
Orçamentos funcionam melhor quando cobrem tanto o que os usuários sentem quanto o que os times podem controlar. Um bom conjunto mistura métricas de experiência (a parte “pareceu rápido?”) com limites de recurso e CPU (o “por que ficou lento?”).
Eles rastreiam como a página se comporta para pessoas reais. Os mais úteis mapeiam diretamente para os Core Web Vitals:
Orçamentos de tempo são sua estrela guia porque correspondem à frustração do usuário. Mas eles nem sempre dizem o que consertar, então você também precisa dos tipos de orçamento abaixo.
Esses são mais fáceis de aplicar em builds e revisões porque são concretos.
Orçamentos de peso limitam coisas como total de JavaScript, total de CSS, peso de imagens e fontes. Orçamentos de requisição limitam contagem total de requisições e scripts de terceiros, reduzindo overhead de rede e trabalho “surpresa” de tags, widgets e trackers. Orçamentos de runtime limitam long tasks, tempo na main-thread e tempo de hidratação (especialmente em React), que muitas vezes explica por que uma página “parece” lenta em celulares de gama média.
Um exemplo prático em React: o tamanho do bundle pode parecer ok, mas um novo carrossel adiciona render pesado no cliente. A página carrega, ainda assim tocar em filtros fica travado porque a hidratação bloqueia a main thread. Um orçamento de runtime como “não ter long tasks acima de X ms durante o startup” ou “hidratação completa em até Y segundos em um dispositivo de médio desempenho” pode detectar isso mesmo quando os orçamentos de peso não o fazem.
A abordagem mais forte trata tudo como um sistema: orçamentos de experiência definem sucesso, e orçamentos de tamanho, requisição e runtime mantêm releases honestos e facilitam responder “o que mudou?”.
Se você definir limites demais, as pessoas param de prestar atenção. Escolha 3 a 5 orçamentos que correspondam ao que os usuários mais sentem e que você possa medir em cada pull request ou release.
Um conjunto prático inicial (ajuste os números depois):
Dois limiares mantêm as coisas sensatas. “Aviso” indica que você está se afastando. “Falha” bloqueia uma release ou exige aprovação explícita. Isso torna o limite real sem criar incêndios constantes.
Escreva o orçamento em um lugar compartilhado para que ninguém debata durante uma release corrida. Seja curto e específico: quais páginas ou fluxos estão cobertos, onde as medições rodam (auditoria local, CI, build staged), qual dispositivo e perfil de rede você usa e exatamente como as métricas são definidas (campo vs lab, gzip vs bruto, por rota vs app inteiro).
Comece com um baseline que você possa repetir. Escolha uma ou duas páginas chave e teste-as no mesmo perfil de dispositivo e rede a cada vez. Rode o teste pelo menos três vezes e registre a mediana para que uma execução estranha não guie sua direção.
Use uma planilha de baseline simples que inclua tanto uma métrica de usuário quanto uma métrica de build. Por exemplo: LCP e INP para a página, mais total de JavaScript e total de bytes de imagem para o build. Isso torna orçamentos reais porque você vê o que o app enviou, não só o que um teste de laboratório estimou.
Defina orçamentos um pouco melhores que hoje, não números de fantasia. Uma regra sólida é melhorar 5–10% a partir da mediana atual para cada métrica que importa. Se seu LCP é 3.2s no setup base, não pule direto para 2.0s. Comece com 3.0s e aperte conforme provar que consegue manter.
Adicione uma checagem rápida a cada release antes dos usuários verem. Mantenha-a rápida para que as pessoas não a ignorem. Uma versão simples: rode uma auditoria de página única na página acordada, falhe o build se JS ou imagens excederem o orçamento, armazene resultados por commit para ver quando algo mudou e sempre teste o mesmo padrão de URL (sem dados aleatórios).
Revise violações semanalmente, não só quando alguém reclamar. Trate uma violação como um bug: identifique a mudança que a causou, decida o que consertar agora e o que agendar. Aperte devagar, só depois de manter a linha por algumas releases.
Quando o escopo do produto mudar, atualize orçamentos deliberadamente. Se você adicionar uma nova ferramenta de analytics ou uma feature pesada, documente o que cresceu (tamanho, requisições, runtime), o que vocês farão para compensar depois e quando o orçamento deve voltar ao normal.
Um orçamento só ajuda se você puder checá-lo rapidamente. O objetivo de uma auditoria de 10 minutos não é provar um número perfeito. É identificar o que mudou desde o último bom build e decidir o que consertar primeiro.
Comece com uma página que represente uso real. Então rode as mesmas checagens rápidas sempre:
Duas visões costumam dar respostas em minutos: o waterfall de rede e a timeline da main-thread.
No waterfall, procure por uma requisição que domine o caminho crítico: um script gigante, uma fonte bloqueante ou uma imagem que começa tarde. Se o recurso do LCP não for solicitado cedo, a página não bate o orçamento de LCP não importa quão rápido o servidor seja.
Na timeline, procure long tasks (50 ms ou mais). Um aglomerado de long tasks no startup geralmente significa JavaScript demais na primeira carga. Um chunk massivo costuma ser problema de roteamento ou um bundle compartilhado que cresceu ao longo do tempo.
Auditorias rápidas falham quando cada execução é diferente. Capture o básico para deixar as mudanças claras: URL da página e versão/build, dispositivo e perfil de rede do teste, descrição do elemento LCP, os números chave que você rastreia (por exemplo LCP, total de JS bytes, contagem de requisições) e uma nota curta sobre o maior culpado.
Testes em desktop servem para feedback rápido e checagens de PR. Use um dispositivo real quando estiver próximo do orçamento, quando a página parecer travada ou quando seus usuários forem majoritariamente mobile. CPUs móveis tornam long tasks óbvias, e é aí que muitas releases “parece ok no meu laptop” falham.
Quando um orçamento falha, o pior é “otimizar tudo”. Use uma ordem de triagem repetível para que cada correção tenha retorno claro.
Comece pelo que os usuários mais notam e depois vá para ajustes mais finos:
Um time envia um novo dashboard e de repente perde o orçamento de LCP. Em vez de ajustar cabeçalhos de cache primeiro, eles descobrem que o elemento LCP é uma imagem de gráfico em full-width. Redimensionam, servem em formato mais leve e carregam só o que importa cedo. Em seguida, notam que uma grande biblioteca de gráficos carrega em todas as rotas. Carregam-na apenas na página de analytics e adiam um widget de suporte de terceiros até a primeira interação. Em um dia, o dashboard volta ao orçamento, e a próxima release tem respostas claras de “o que mudou”.
O maior modo de falha é tratar orçamentos como um documento único. Orçamentos só funcionam quando são fáceis de checar, difíceis de ignorar e ligados a como você entrega.
A maioria dos times cai em alguns atalhos:
Um padrão comum é uma feature “pequena” que puxa uma nova biblioteca. O bundle cresce, o LCP atrasa um segundo em redes lentas e ninguém nota até tickets de suporte. Orçamentos existem para tornar essa mudança visível na revisão.
Comece simples e mantenha checagens consistentes. Escolha 2–4 orçamentos que mapeiem para experiência do usuário e aperte-os gradualmente. Trave seu setup de teste e registre-o. Rastreie pelo menos um sinal de usuário real se puder e use testes de laboratório para explicar o “porquê”, não para vencer discussões. Quando uma dependência adicionar peso relevante, exija uma nota curta: quanto custa, o que substitui e por que vale a pena. O mais importante: coloque a checagem de orçamento no caminho normal de release.
Se orçamentos parecerem fricção constante, geralmente são irreais para hoje ou não estão ligados a decisões reais. Corrija essas duas coisas primeiro.
Um time pequeno lançou um dashboard analytics em React em uma semana. No começo parecia rápido, mas a cada release de sexta ele ficava um pouco mais pesado. Depois de um mês, usuários começaram a dizer que a primeira tela “travava” e filtros pareciam lentos.
Eles pararam de discutir “rápido o suficiente” e escreveram orçamentos ligados ao que os usuários notam:
A primeira falha apareceu em dois pontos. O bundle inicial subiu conforme gráficos, bibliotecas de data e um kit de UI foram adicionados. Ao mesmo tempo, a imagem de cabeçalho do dashboard foi trocada por um arquivo maior “só por agora”, empurrando o LCP além do limite. O INP piorou porque cada mudança de filtro disparava rerenders pesados e cálculos caros na main thread.
Eles consertaram numa ordem que gerou ganhos rápidos e preveniu regressões:
Reverter o LCP para dentro do limite redimensionando e comprimindo imagens, definindo dimensões explícitas e evitando fontes bloqueantes.
Reduzir o JS inicial removendo bibliotecas não usadas, dividindo rotas não críticas e lazy-loading de gráficos.
Melhorar o INP memoizando componentes caros, debouncing em filtros de digitação e movendo trabalho pesado para fora do caminho crítico.
Adicionar uma checagem de orçamento a cada release para que, se uma métrica quebrar, a release espere.
Depois de duas releases, o LCP caiu de 3.4s para 2.3s, e o INP melhorou de cerca de 350ms para menos de 180ms no mesmo dispositivo de teste.
Um orçamento só ajuda se as pessoas puderem segui-lo do mesmo jeito toda vez. Mantenha pequeno, documente e torne parte do envio.
Escolha algumas métricas que se encaixem no seu app, defina limiares de “aviso vs falha” e documente exatamente como você testa (dispositivo, navegador, rede, página/fluxo). Salve um relatório baseline do melhor release atual e rotule claramente. Decida o que conta como exceção válida e o que não conta.
Antes de cada release, rode a mesma auditoria e compare com o baseline. Se algo regredir, registre onde você rastreia bugs e trate como uma etapa de checkout quebrada, não como uma tarefa “depois”. Se você enviar com uma exceção, registre um responsável e uma data de expiração (frequentemente 1–2 sprints). Se a exceção for renovada continuamente, o orçamento precisa de discussão real.
Leve orçamentos para mais cedo no planejamento e nas estimativas: “Esta tela adiciona uma biblioteca de gráficos, então precisamos remover algo ou lazy-load”. Se você está construindo com Koder.ai (koder.ai), também pode escrever essas restrições desde o início no Modo de Planejamento, iterar em fatias menores e usar snapshots e rollback quando uma mudança ultrapassar o limite. O ponto não é a ferramenta, é o hábito: cada nova feature tem que pagar pelo seu peso, ou não é enviada.
Um orçamento de desempenho é um conjunto de limites rígidos (tempo, tamanho, requisições, trabalho de CPU) que seu time concorda antes de construir.
Se uma mudança ultrapassa o limite, trate-a como um requisito quebrado: corrija, reduza o escopo ou aprove explicitamente uma exceção com um responsável e uma data de expiração.
Porque o desempenho piora gradualmente. Cada feature adiciona JavaScript, CSS, imagens, fontes, chamadas de API e tags de terceiros.
Orçamentos interrompem essa degradação ao forçar um trade-off: se você adicionar peso ou trabalho, precisa compensar (lazy-load, dividir rotas, simplificar UI, remover dependências).
Escolha uma jornada real do usuário e um setup de teste consistente.
Um bom começo é algo frequente e crítico para o negócio, por exemplo:
Evite casos de borda no começo; você quer um fluxo que possa medir a cada release.
Comece com um alvo que corresponda aos usuários típicos, por exemplo:
Anote e mantenha estável. Se você mudar dispositivo, rede, estado de cache ou o caminho testado, sua tendência vira ruído.
Use um conjunto pequeno que cubra o que os usuários sentem e o que os times podem controlar:
Um conjunto prático inicial é:
Use dois limiares:
Isso evita alarmes constantes enquanto mantém o limite real quando cruzado.
Faça esta sequência:
Nem sempre. O tamanho do bundle pode estar OK enquanto a página ainda parece lenta porque a main thread está ocupada.
Causas comuns em React:
Adicione um orçamento de runtime (por exemplo, limite de long tasks durante o startup ou um teto de tempo de hidratação) para capturar esse tipo de problema.
Geração e iteração rápidas podem acrescentar dependências, floreios de UI e scripts de terceiros que são entregues a todos.
A solução é tornar os orçamentos parte do fluxo:
Isso evita que iteração rápida vire produto lento.
Métricas de timing mostram a dor; limites de tamanho e runtime ajudam a achar rapidamente a causa.
Escolha 3–5 orçamentos primeiro. Ajuste depois com base no seu baseline e histórico de releases.
Trate a quebra como um bug: identifique o commit, corrija ou reduza o escopo e previna repetições.