Web performance budget: como definir e respeitar limites de tamanho
1. O que é um Performance Budget e por que ele é crítico hoje
Um performance budget (orçamento de performance) é um conjunto de limites estabelecidos para métricas que afetam a experiência do usuário e o desempenho de uma aplicação web. O conceito surgiu da necessidade de tratar performance como um requisito não funcional mensurável, assim como tratamos orçamentos financeiros em projetos.
O impacto real no negócio é inegável: estudos do Google mostram que 53% dos usuários abandonam sites que demoram mais de 3 segundos para carregar. Para cada segundo adicional de carregamento, as taxas de conversão podem cair até 20%. Além disso, desde 2021, o Google utiliza as Core Web Vitals como fator de ranqueamento, tornando a performance um requisito de SEO.
Existem duas abordagens principais para definir um performance budget:
- Quantitativo: foca em limites de peso total (ex: 500KB de JavaScript, 1MB de imagens) e tempo de carregamento (ex: TTI < 3s em 3G).
- Qualitativo: foca em métricas de experiência como Largest Contentful Paint (LCP < 2.5s), First Input Delay (FID < 100ms) e Cumulative Layout Shift (CLS < 0.1).
2. Métricas essenciais para definir seu orçamento
Para criar um orçamento eficaz, é preciso monitorar métricas específicas:
Time to Interactive (TTI) e First Contentful Paint (FCP) são métricas que se relacionam diretamente com o tamanho dos recursos. Um bundle de JavaScript de 500KB pode levar 2 segundos para ser processado em dispositivos móveis médios.
Peso máximo por tipo de recurso:
JavaScript: 300KB (inicial) - 500KB (máximo)
CSS: 50KB (inicial) - 100KB (máximo)
Imagens: 200KB (por imagem) - 1MB (total na viewport)
Fontes: 50KB (total)
Lighthouse Score mínimo: defina uma meta de pelo menos 90 em performance para dispositivos móveis, 90 em acessibilidade e 90 em boas práticas.
3. Como estabelecer limites realistas para cada recurso
O primeiro passo é realizar um benchmark contra concorrentes e médias do setor. O HTTP Archive fornece dados atualizados sobre o peso médio de páginas web:
Média global (2024):
- Peso total da página: 2.5MB
- JavaScript: 500KB
- Imagens: 1.2MB
- CSS: 80KB
Para calcular o budget baseado na conexão real do usuário, considere:
Conexão 3G lenta: 400Kbps
Conexão 4G média: 5Mbps
Conexão 5G: 50Mbps
Budget calculado para 3G (carregamento em 5 segundos):
- Peso máximo: 400Kbps * 5s = 2Mbps = 250KB
Adote uma estratégia de orçamento progressivo:
- Budget inicial: 500KB JS, 200KB CSS, 1MB imagens (para MVP)
- Budget intermediário: 300KB JS, 100KB CSS, 500KB imagens (após otimizações)
- Budget ideal: 200KB JS, 50KB CSS, 300KB imagens (para máxima performance)
4. Ferramentas para monitorar e validar o orçamento
WebPageTest e Lighthouse CI permitem automatizar a validação em pipelines de CI/CD:
# Exemplo de configuração no Lighthouse CI
{
"ci": {
"assert": {
"assertions": {
"categories:performance": ["error", {"minScore": 0.9}],
"resource-summary:script:size": ["error", {"maxNumericValue": 300000}],
"resource-summary:stylesheet:size": ["error", {"maxNumericValue": 50000}]
}
}
}
}
Bundlers e plugins:
- webpack-bundle-analyzer: visualiza o tamanho de cada módulo
- size-limit: verifica o tamanho do bundle em PRs
- bundlesize: compara o tamanho atual com o orçamento definido
Budgets nativos no Chrome DevTools e no Next.js:
// next.config.js
module.exports = {
experimental: {
performanceBudget: {
totalSize: 500000, // 500KB
imageSize: 200000, // 200KB
fontSize: 50000 // 50KB
}
}
}
5. Técnicas para respeitar o orçamento de JavaScript
Code splitting por rota e por componente:
// Em vez de importar tudo de uma vez
import { Chart } from 'heavy-chart-library'
// Use dynamic imports
const Chart = dynamic(() => import('heavy-chart-library'), {
loading: () => <Skeleton />
})
Tree shaking eficiente e remoção de dependências desnecessárias:
// Verifique o que está sendo importado
import { map } from 'lodash' // Evite importar toda a biblioteca
// Prefira:
const map = (arr, fn) => arr.map(fn)
Substituição de bibliotecas pesadas:
Bibliotecas pesadas → Alternativas leves
jQuery (87KB) → Vanilla JS ou Alpine.js (7KB)
Moment.js (230KB) → date-fns (17KB) ou Day.js (2KB)
Lodash (71KB) → Funções nativas ou micro-libraries
6. Otimização de assets visuais para manter o budget
Imagens responsivas com srcset e formatos modernos:
<img
src="foto-800.webp"
srcset="foto-400.webp 400w, foto-800.webp 800w, foto-1200.webp 1200w"
sizes="(max-width: 600px) 100vw, 800px"
alt="Descrição"
loading="lazy"
/>
Fontes sob medida:
/* Subsetting: remova caracteres desnecessários da fonte */
/* font-display: swap evita FOIT (Flash of Invisible Text) */
@font-face {
font-family: 'MinhaFonte';
src: url('/fonts/minhafonte-subset.woff2') format('woff2');
font-display: swap;
unicode-range: U+0000-00FF; /* Apenas caracteres latinos básicos */
}
CSS crítico inline e lazy loading de estilos não essenciais:
<!-- CSS crítico inline no <head> -->
<style>
/* Estilos para o conteúdo acima da dobra */
header, nav, .hero { display: block; }
</style>
<!-- CSS não crítico carregado assíncronamente -->
<link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
7. Automatizando a governança do orçamento no fluxo de desenvolvimento
Integração contínua com falha automática:
# .github/workflows/performance-budget.yml
name: Performance Budget Check
on: [pull_request]
jobs:
budget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- run: npx size-limit
- run: npx lighthouse-ci https://staging.example.com
Alertas e dashboards para equipes de frontend podem ser configurados com ferramentas como Datadog, Grafana ou até mesmo planilhas compartilhadas que monitoram a evolução do peso do bundle a cada deploy.
Revisão periódica do orçamento: a cada trimestre, reavalie os limites com base na evolução da aplicação, nos novos recursos e no perfil dos usuários (que podem estar migrando para conexões mais rápidas).
8. Casos reais e armadilhas comuns ao definir budgets
Exemplo para um portal editorial vs. uma SPA pesada:
Portal editorial (notícias):
- Budget: 200KB JS, 50KB CSS, 500KB imagens
- Prioridade: FCP < 1.5s, LCP < 2s
SPA de dashboard (gráficos interativos):
- Budget: 500KB JS, 100KB CSS, 200KB imagens
- Prioridade: TTI < 3s, interatividade rápida
O erro de focar apenas no peso total: um site com 1MB de JS bem dividido em chunks pode carregar mais rápido que um com 300KB de JS monolítico. A latência da rede e a forma como os recursos são entregues importam tanto quanto o peso.
Como lidar com exceções justificadas: animações complexas, gráficos interativos ou bibliotecas de terceiros (como players de vídeo) podem estourar o budget. Nesses casos, documente a exceção, estabeleça um prazo para revisão e considere carregar esses recursos apenas sob demanda.
// Exemplo de justificativa documentada
/*
* Exceção aprovada em 15/03/2024
* Biblioteca de gráficos: 150KB (orçamento: 50KB)
* Motivo: visualização de dados complexa para o módulo de analytics
* Revisão agendada: 15/06/2024
* Responsável: João Silva
*/
Referências
- Web Performance Budgets (Google Web Fundamentals) — Guia oficial do Google sobre como definir e implementar orçamentos de performance, com exemplos práticos e métricas recomendadas.
- Performance Budget Calculator (WebPageTest) — Ferramenta interativa para calcular orçamentos baseados em conexões reais de usuários, com dados do HTTP Archive.
- Using Lighthouse CI to Set Performance Budgets (Addy Osmani) — Artigo técnico detalhado sobre automação de orçamentos com Lighthouse CI em pipelines de CI/CD.
- Size Limit: Prevent JavaScript Libraries from Bloating Your Bundle — Ferramenta open source que verifica o tamanho de bundles em PRs e falha automaticamente se o orçamento for excedido.
- HTTP Archive: State of the Web Report — Relatório anual com dados estatísticos sobre o peso médio de páginas web, distribuição de recursos e tendências de performance.
- Core Web Vitals and Performance Budgets (Smashing Magazine) — Tutorial prático que conecta as métricas Core Web Vitals com a definição de orçamentos realistas para projetos web.
- Webpack Bundle Analyzer — Plugin que gera visualizações interativas do conteúdo do bundle, essencial para identificar módulos que estouram o orçamento de JavaScript.