O que são Core Web Vitals na prática
Core Web Vitals (CWV) são um conjunto de métricas que medem, com foco no usuário, se uma página “parece rápida”, “responde rápido” e “não fica pulando” enquanto carrega e durante o uso. Elas não medem apenas tempo de download ou tamanho de arquivos; elas traduzem a experiência percebida em números observáveis. Na prática, CWV servem como objetivos de performance que você pode acompanhar ao longo do tempo, comparar entre páginas e usar para priorizar melhorias com impacto real.
As três métricas principais são:
- LCP (Largest Contentful Paint): quanto tempo leva para o maior elemento visível “principal” aparecer na tela (geralmente hero image, banner, título grande ou bloco de conteúdo).
- INP (Interaction to Next Paint): quão rápido a página responde visualmente após uma interação do usuário (clique, toque, teclado). Substitui o FID como métrica principal de responsividade.
- CLS (Cumulative Layout Shift): quanto a página “pula” inesperadamente durante o carregamento e uso, gerando cliques errados e sensação de instabilidade.
Essas métricas são avaliadas com base em dados reais de usuários (field data) e também podem ser simuladas em laboratório (lab data). Entender a diferença é essencial para definir objetivos realistas e para não otimizar “para o teste” em vez de otimizar para pessoas.
Objetivos de performance: metas numéricas e por que elas existem
Um objetivo de performance bem definido evita discussões vagas como “o site está lento” e transforma a conversa em critérios verificáveis. Para CWV, as metas recomendadas (para a maioria dos sites) são:
- LCP: bom se ≤ 2,5 s; precisa melhorar entre 2,5 s e 4,0 s; ruim se > 4,0 s.
- INP: bom se ≤ 200 ms; precisa melhorar entre 200 ms e 500 ms; ruim se > 500 ms.
- CLS: bom se ≤ 0,1; precisa melhorar entre 0,1 e 0,25; ruim se > 0,25.
Além das metas, existe um detalhe importante: a avaliação costuma considerar percentis (por exemplo, p75). Isso significa que você não quer apenas que “na média” esteja bom; você quer que a maior parte dos usuários tenha uma experiência boa. Em termos práticos, mirar no p75 reduz o risco de uma parcela relevante de usuários (com dispositivos mais lentos, rede pior, CPU ocupada) ficar com experiência ruim.
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
Como transformar metas em critérios de aceite
Para usar CWV como objetivo de engenharia, transforme as metas em critérios de aceite por tipo de página e por contexto:
- Por template: home, listagem, produto/artigo, checkout, busca interna.
- Por dispositivo: mobile costuma ser o foco principal; desktop pode ter metas mais fáceis, mas não deve ser ignorado.
- Por rede: 4G/3G (ou “slow 4G”) para simulações; no campo, haverá variação.
Exemplo de critério de aceite para uma página de produto: “No mobile, p75 de LCP ≤ 2,5 s, p75 de INP ≤ 200 ms e p75 de CLS ≤ 0,1, medidos em produção por 28 dias; em laboratório, LCP ≤ 2,5 s e CLS ≤ 0,1 em ‘slow 4G’ e CPU 4x slowdown”.
Field data vs lab data: como usar cada um sem confusão
Field data (dados de campo) vem de usuários reais. Ele captura diversidade de dispositivos, redes, extensões, cache, rotas de navegação e comportamento. É o melhor indicador de experiência real, mas tem limitações: demora para refletir mudanças, pode ter ruído e nem sempre permite reproduzir exatamente um problema.
Lab data (dados de laboratório) vem de testes controlados (por exemplo, Lighthouse/DevTools). Ele é ótimo para depurar, comparar antes/depois e iterar rápido. Porém, não representa toda a variabilidade do mundo real e pode ser “enganado” por condições artificiais.
Uso prático recomendado:
- Use field para definir prioridade (quais páginas e usuários estão sofrendo) e para validar resultado (melhorou de verdade para usuários).
- Use lab para diagnosticar (o que está causando) e para testar hipóteses rapidamente.
Entendendo LCP: o que realmente atrasa o “conteúdo principal”
LCP mede o tempo até o maior elemento de conteúdo visível ser renderizado. Na prática, LCP costuma ser afetado por quatro grupos de causas:
- Tempo de resposta do servidor (TTFB alto): o navegador fica esperando o HTML inicial.
- Bloqueio de renderização: CSS e JS que impedem a pintura inicial.
- Carregamento do recurso do LCP: imagem grande sem prioridade, fonte que atrasa texto, ou mídia pesada.
- Tempo de renderização: CPU ocupada com JS, layout complexo, hidratação pesada.
Como identificar qual elemento é o LCP
Antes de otimizar, descubra qual é o elemento que está sendo contado como LCP. Em laboratório, ferramentas costumam indicar o elemento (por exemplo, uma imagem hero ou um bloco de texto). Em produção, você pode instrumentar via API de Performance para registrar o LCP e o seletor/URL do recurso associado.
Passo a passo prático para melhorar LCP (sem “chutar”)
Use este fluxo para atacar LCP de forma sistemática:
- 1) Confirmar o elemento LCP: é imagem? texto? vídeo? um container?
- 2) Medir TTFB: se o HTML demora a chegar, otimizações de front-end terão teto baixo.
- 3) Verificar bloqueios: CSS crítico, JS no head, fontes bloqueando texto.
- 4) Priorizar o recurso do LCP: garantir que a imagem/fonte principal seja solicitada cedo e com prioridade.
- 5) Reduzir trabalho no main thread: menos JS antes do LCP, menos hidratação, menos layout thrashing.
Exemplo prático: se o LCP é uma imagem hero, você quer que ela seja descoberta cedo, baixada rápido e decodificada sem atrasos. Algumas ações típicas:
- Evitar que a URL da imagem só apareça depois de executar JS.
- Usar formatos modernos (AVIF/WebP) e dimensões adequadas.
- Definir
fetchprioritye/oupreloadquando fizer sentido.
<!-- Exemplo: imagem LCP com prioridade e dimensões definidas -->
<img src="/img/hero.avif" width="1200" height="600" alt="" fetchpriority="high" decoding="async" />
<!-- Opcional: preload quando a imagem é sempre a LCP e está no topo -->
<link rel="preload" as="image" href="/img/hero.avif" />O objetivo não é “preload em tudo”, e sim garantir que o recurso do LCP não fique competindo com dezenas de outros downloads iniciados antes dele.
Entendendo INP: responsividade real, não só “tempo de clique”
INP mede a latência de interações ao longo da vida da página, focando na pior (ou nas piores) interações representativas. Ele captura o tempo entre o usuário interagir e a próxima atualização visual ocorrer. Na prática, INP piora quando o navegador está ocupado e não consegue processar eventos rapidamente.
Causas comuns de INP ruim:
- Long tasks no main thread (tarefas > 50 ms), geralmente por JS pesado.
- Handlers de evento caros: clique dispara validações, re-renderizações, cálculos, parsing.
- Renderização cara: mudanças de DOM que causam layout/reflow e paint custosos.
- Terceiros: tags de analytics/ads que competem por CPU.
Como pensar em INP como orçamento de tempo
Para manter INP ≤ 200 ms, você precisa que o caminho crítico de uma interação (event handling + render) seja curto. Um modelo mental útil é: “cada interação importante deve caber em poucos frames”. Em telas de 60 Hz, um frame tem ~16,7 ms; não significa que você precisa de 16 ms, mas ajuda a visualizar que 200 ms é um limite que pode ser estourado facilmente por algumas tarefas longas.
Passo a passo prático para melhorar INP
- 1) Descobrir quais interações estão ruins: cliques em menu, abrir modal, filtrar lista, digitar em busca.
- 2) Encontrar long tasks: identificar scripts e funções que bloqueiam o main thread.
- 3) Quebrar trabalho: dividir tarefas longas em partes menores, adiar trabalho não essencial.
- 4) Reduzir re-render: evitar atualizações globais quando só um componente muda.
- 5) Controlar terceiros: carregar sob demanda, atrasar, remover o que não agrega.
Exemplo prático: um clique em “Filtrar” dispara uma função que percorre milhares de itens e atualiza o DOM inteiro. Em vez disso, você pode:
- Pré-computar índices (quando possível) fora do caminho da interação.
- Paginar/virtualizar listas grandes.
- Atualizar apenas a parte visível.
// Exemplo conceitual: quebrando uma tarefa longa em partes menores
function processInChunks(items, chunkSize, onChunk, onDone) {
let i = 0;
function run() {
const end = Math.min(i + chunkSize, items.length);
for (; i < end; i++) onChunk(items[i]);
if (i < items.length) {
// libera o main thread antes de continuar
setTimeout(run, 0);
} else {
onDone();
}
}
run();
}Esse padrão não resolve tudo, mas ilustra a ideia central: evitar bloquear o main thread por tempo demais durante uma interação.
Entendendo CLS: estabilidade visual e previsibilidade
CLS mede a soma de mudanças inesperadas de layout. O ponto-chave é “inesperadas”: se o usuário interage e a interface muda como resultado direto (por exemplo, abrir um accordion), isso normalmente não conta como shift problemático. O que conta é quando elementos mudam de lugar sem o usuário pedir, como quando uma imagem carrega e empurra o texto, ou quando um banner aparece no topo e desloca tudo.
Causas comuns de CLS alto:
- Imagens/iframes sem dimensões: o navegador não reserva espaço.
- Conteúdo injetado acima do conteúdo existente: banners, avisos, ads.
- Fontes web que trocam métricas e mudam o tamanho do texto.
- Componentes que expandem após carregar dados sem reservar espaço.
Passo a passo prático para reduzir CLS
- 1) Reservar espaço para mídia: sempre definir
width/heightou usaraspect-ratio. - 2) Evitar inserções no topo: se precisar mostrar um banner, prefira sobrepor (overlay) ou reservar área fixa desde o início.
- 3) Tratar fontes: escolher estratégia de carregamento que minimize mudanças visuais e ajustar fallback.
- 4) Skeletons com altura estável: placeholders devem ter dimensões próximas do conteúdo final.
/* Exemplo: reservar proporção para evitar shift em imagens responsivas */
.hero {
aspect-ratio: 16 / 9;
width: 100%;
overflow: hidden;
}
.hero img {
width: 100%;
height: 100%;
object-fit: cover;
}Para componentes que dependem de dados (por exemplo, um card que mostra preço e parcelamento), evite renderizar “nada” e depois empurrar o layout. Renderize um placeholder com a mesma altura aproximada e troque o conteúdo sem alterar o fluxo.
Orçamentos de performance: como definir limites além das métricas
Metas de CWV dizem “como está a experiência”. Orçamentos de performance dizem “quanto você pode gastar” para manter a experiência boa. Eles ajudam a prevenir regressões quando o produto cresce.
Exemplos de orçamentos úteis:
- JavaScript: limite de KB transferidos e, principalmente, limite de tempo de execução no main thread.
- Imagens: tamanho máximo para imagens acima da dobra e número de requests iniciais.
- Fontes: número de famílias/variantes e tamanho total.
- Terceiros: número de scripts e impacto de CPU.
Um orçamento simples e prático pode ser: “na rota de produto, até 170 KB de JS comprimido no carregamento inicial” e “nenhuma tarefa no main thread acima de 200 ms durante o carregamento”. O valor exato depende do seu público e do tipo de aplicação, mas o importante é existir um limite que acione revisão quando ultrapassado.
Como medir na prática: checklist de instrumentação e leitura
Para trabalhar com CWV de forma contínua, você precisa de um ciclo de medição. Um checklist prático:
- 1) Medir em laboratório para depurar: rode auditorias com condições controladas e registre LCP/INP/CLS.
- 2) Medir em produção para validar: capture CWV via APIs do navegador e envie para seu endpoint de métricas.
- 3) Segmentar: separar por página/template, dispositivo, conexão, país, e também por “usuários novos vs recorrentes”.
- 4) Correlacionar: quando CWV piora, correlacione com deploys, campanhas, mudanças de terceiros.
Exemplo de instrumentação conceitual (simplificada) para capturar métricas web vitals e enviar para um endpoint. A implementação real pode variar, mas a ideia é registrar e anexar contexto (rota, device, conexão):
// Pseudocódigo: enviar métricas para um endpoint
function sendMetric(name, value, attrs = {}) {
navigator.sendBeacon(
'/metrics',
JSON.stringify({ name, value, attrs, ts: Date.now() })
);
}
// Exemplo: ao obter LCP/CLS/INP via biblioteca ou PerformanceObserver,
// chame sendMetric('LCP', lcpValue, { route: location.pathname })Mesmo sem entrar em detalhes de biblioteca, o ponto é: sem dados de produção, você pode “melhorar no laboratório” e ainda assim não mover o p75 real, porque o gargalo pode estar em dispositivos mais fracos, em rotas específicas, em conteúdo dinâmico ou em scripts de terceiros que não aparecem no seu cenário de teste.
Priorização: o que atacar primeiro quando tudo parece importante
Quando você mede, normalmente encontra vários problemas ao mesmo tempo. Para priorizar, use uma matriz simples baseada em impacto no usuário e esforço:
- Primeiro: problemas que afetam o elemento LCP (acima da dobra) e shifts visíveis (CLS), porque impactam a primeira impressão e a leitura.
- Depois: INP em interações críticas do funil (buscar, filtrar, adicionar ao carrinho, login, finalizar).
- Em paralelo: reduzir JS e terceiros, porque melhora LCP e INP ao mesmo tempo.
Um método prático é escolher 1 ou 2 templates com maior tráfego e pior p75, e trabalhar neles até estabilizar. Otimizar “um pouco em tudo” frequentemente não move as métricas o suficiente para sair da zona “precisa melhorar”.
Exemplos de objetivos por tipo de página
Nem toda página tem o mesmo perfil. Definir objetivos por tipo de página torna as metas mais realistas e acionáveis.
Página de conteúdo (artigo/blog/documentação)
- LCP: geralmente dominado por título e imagem hero; meta ≤ 2,5 s.
- CLS: atenção a embeds, iframes e imagens no corpo; meta ≤ 0,1.
- INP: costuma ser bom por natureza, mas pode piorar com scripts de comentários/ads; meta ≤ 200 ms.
Listagem com filtros (e-commerce, catálogo, busca)
- LCP: pode ser o grid inicial; meta ≤ 2,5 s.
- INP: crítico em filtros, ordenação, paginação; meta ≤ 200 ms.
- CLS: cuidado com carregamento incremental que muda alturas; meta ≤ 0,1.
Aplicação com muita interatividade (dashboard, web app)
- LCP: ainda importa, mas o maior risco é CPU/JS; meta ≤ 2,5 s (ou uma meta interna ligeiramente mais flexível se houver justificativa).
- INP: principal indicador de qualidade; meta ≤ 200 ms.
- CLS: modais, toasts e painéis devem ser previsíveis; meta ≤ 0,1.
Armadilhas comuns ao definir metas de Core Web Vitals
Otimizar apenas para o laboratório
Se você só olha o Lighthouse local, pode ignorar problemas que só aparecem em produção: cache frio, conteúdo personalizado, A/B tests, scripts de terceiros, dispositivos low-end. Use laboratório para depurar, mas valide com dados reais.
Confundir “carregou” com “está utilizável”
Uma página pode carregar rápido e ainda assim ter INP ruim porque o main thread está ocupado com hidratação, parsing de bundles, ou re-renderizações. Por isso CWV é útil: ele mede o que o usuário sente, não apenas o que a rede entregou.
Preload e prioridades usados sem critério
Marcar tudo como prioridade alta cria competição e pode piorar o LCP. O objetivo é priorizar o que realmente define a primeira dobra: o recurso do LCP e CSS essencial.
Corrigir CLS “na marra” com alturas fixas erradas
Reservar espaço é correto, mas usar alturas fixas que não batem com o conteúdo final pode criar espaços em branco ou cortes. Prefira proporções (aspect-ratio) e skeletons que se aproximem do layout final.
Roteiro prático: criando um plano de performance orientado a CWV
Para fechar o capítulo com algo aplicável, aqui vai um roteiro que você pode executar em um projeto real:
- 1) Escolha 2 templates com maior tráfego e piores métricas (ex.: home e produto).
- 2) Defina metas (LCP/INP/CLS) por template e por mobile.
- 3) Instrumente produção para capturar CWV com contexto (rota, device, conexão).
- 4) Rode testes de laboratório para cada template e registre: elemento LCP, recursos bloqueantes, long tasks, shifts.
- 5) Crie backlog por causa raiz: LCP (servidor/prioridade/imagem/CSS/JS), INP (long tasks/handlers/render), CLS (dimensões/injeções/fontes).
- 6) Aplique correções em pequenos lotes e valide em laboratório e em produção.
- 7) Estabeleça guardrails: orçamentos de JS/imagens/terceiros e checagens em PR/CI para evitar regressões.
Esse roteiro ajuda a manter o foco: medir, identificar o gargalo dominante, corrigir com intenção e validar com dados reais. A partir daí, CWV deixa de ser um “misterioso score” e vira um sistema de objetivos de performance que guia decisões de front-end no dia a dia.