Web Vitals: LCP, FCP, TTFB, CLS, INP
As cinco métricas que o Google usa pra rankear seu site. Esse guia explica o que cada uma mede, qual o limite entre "bom" e "ruim", e o que efetivamente causa um score ruim em cada caso.
Por que importa. Desde 2021 o Google usa Core Web Vitals como sinal de ranking em busca mobile. Sites com vitais ruins perdem posição mesmo com conteúdo de qualidade. E PageSpeed Insights na sua máquina não é o que o Google vê — o Google usa CrUX (Chrome User Experience Report), dados de visitantes reais. O Radar mede o mesmo: RUM (Real User Monitoring), não simulação.
Resumo das 5 métricas
| Métrica | Mede | Bom | Ruim | Core Web Vital? |
|---|---|---|---|---|
| LCP | Tempo até o conteúdo principal aparecer | ≤ 2.5s | > 4.0s | Sim |
| INP | Latência de interação (clique, tecla) | ≤ 200ms | > 500ms | Sim (substituiu FID em 03/2024) |
| CLS | Quanto a página "pula" ao carregar | ≤ 0.1 | > 0.25 | Sim |
| FCP | Tempo até o primeiro pixel ser pintado | ≤ 1.8s | > 3.0s | Diagnóstico (não rankeia) |
| TTFB | Tempo de resposta do servidor | ≤ 800ms | > 1800ms | Diagnóstico (não rankeia) |
LCP Core Web Vital
Largest Contentful Paint. Tempo entre o início do load e o momento em que o maior elemento visível (geralmente uma imagem, vídeo ou bloco de texto grande) aparece na tela.
Causas comuns de LCP ruim
- Imagem hero não otimizada. JPG/PNG de 2MB+ servidos sem WebP/AVIF. A maior imagem da página geralmente É o LCP element.
- Fonte web bloqueando render.
@font-facesemfont-display: swapfaz o browser esperar a fonte baixar antes de pintar texto. - CSS crítico em arquivo externo. O browser não pinta nada até baixar e parsear o CSS.
- Servidor lento. Se o TTFB já é > 1s, o LCP nunca vai ficar bom — o trabalho começa atrasado.
- JavaScript bloqueando.
<script>semasync/deferem cima do<head>trava o parser. - Lazy-loading do hero. Erro clássico:
loading="lazy"na imagem principal acima da dobra. Useloading="eager"+fetchpriority="high"no hero.
Como melhorar LCP
- Identifique o elemento LCP no Radar (painel Vitals → URL com pior LCP).
- Se for imagem: converta pra WebP/AVIF, sirva com
srcsetresponsivo, adicionefetchpriority="high"eloading="eager". - Se for texto: garanta
font-display: swapnas@font-facee preload da fonte (<link rel="preload" as="font">). - Habilite cache do servidor (WP Rocket, LiteSpeed, Cloudflare APO) — derruba TTFB.
- Inline o CSS crítico above-the-fold; deixe o resto async.
INP Core Web Vital (substituiu FID em 03/2024)
Interaction to Next Paint. Latência da pior interação do usuário durante toda a vida da página — o tempo entre o usuário tocar/clicar/teclar e o próximo frame visualmente atualizado. Substituiu o FID porque mede TODAS as interações, não só a primeira.
Causas comuns de INP ruim
- Long tasks de JavaScript. Qualquer task > 50ms na main thread bloqueia interação. Frameworks (React, Vue) com renders pesados são o suspeito #1.
- Handlers de evento síncronos pesados. Um
onClickque faz processamento longo sem yield. - Scripts de terceiros. Tag manager, chat widgets, A/B testing — tudo que roda
setIntervalou observers continuamente. - Re-renders desnecessários. Em React/Vue, falta de memoization faz tree inteira re-renderizar a cada keystroke.
- DOM gigante. Páginas com > 1500 nodes têm INP ruim por design — o browser gasta tempo recalculando layout/style.
Como melhorar INP
- No Radar (painel Vitals), procure URLs com INP alto + alto volume de interação — geralmente forms, search, filtros.
- Use
requestIdleCallbackousetTimeout(fn, 0)pra quebrar long tasks. - Defer scripts de terceiros pra depois do
loadevent. - Em React:
useMemo,useCallback,React.memoem componentes pesados. - Reduza tamanho do DOM. Virtualize listas longas.
- Habilite "Throttle CPU 4x" no DevTools pra reproduzir o problema localmente.
CLS Core Web Vital
Cumulative Layout Shift. Quanto o conteúdo da página "pula" sem ação do usuário. Score acumulado: cada deslocamento de layout soma uma fração proporcional à área afetada × distância do shift. Sem unidade — quanto mais perto de 0, melhor.
Causas comuns de CLS ruim
- Imagens sem dimensão.
<img>semwidth/heightfaz o browser não reservar espaço — quando carrega, o resto pula. - Ads/iframes inseridos depois do load. Aparecem do nada e empurram conteúdo.
- FOIT (Flash of Invisible Text) → FOUT. Texto aparece com fonte fallback, depois trocar pra a fonte web faz reflow.
- Banners de cookie aparecendo atrasados. Especialmente os que aparecem no topo da página depois do conteúdo renderizar.
- Conteúdo carregado via JS (skeletons, infinite scroll mal implementado).
Como melhorar CLS
- Sempre defina
widtheheightem<img>e<iframe>(o aspect-ratio é calculado automaticamente desde 2020). - Reserve espaço pra ads/embeds com CSS (
min-height). - Use
font-display: optionalou preload da fonte pra evitar swap visível. - Cookie banner em bottom, não top — ou modal que NÃO empurra conteúdo.
- Pra animações, use
transform/opacityem vez de mudartop/left/height.
FCP Diagnóstico
First Contentful Paint. Tempo até o primeiro pixel de conteúdo (texto, imagem, SVG) ser pintado. Não é Core Web Vital (não rankeia diretamente) mas é diagnóstico chave: se FCP é alto, LCP também vai ser.
Causas comuns de FCP ruim
- TTFB alto. O browser não consegue pintar nada até receber o HTML.
- Render-blocking CSS/JS. Tags
<link rel="stylesheet">e<script>sem async no<head>. - Redirecionamentos em cadeia. Cada redirect adiciona latência.
- HTML gigante. > 100KB de HTML demora pra parsear.
Como melhorar FCP
- Otimize TTFB primeiro (ver abaixo).
- Inline critical CSS (above-the-fold) no
<head>; defira o resto. - Adicione
asyncoudeferem todo<script>. - Evite redirects: link direto pro destino final.
- Habilite compressão (gzip/brotli) no servidor.
TTFB Diagnóstico
Time to First Byte. Tempo entre o request HTTP sair do browser e o primeiro byte da resposta chegar. Mede só a latência do servidor + rede — não inclui parse, render, nada.
Causas comuns de TTFB ruim
- Hosting compartilhado lento. A causa #1 em WordPress. Hosting compartilhado de R$ 10/mês compartilha CPU e disco com 200 outros sites.
- Sem cache de página. Cada request executa PHP, queries de DB, plugins. Cache full-page reduz TTFB de 1s pra < 50ms.
- Plugins WP pesados. Page builders rodando lógica no front-end, plugins SEO fazendo queries em cada page load, etc.
- DB sem índices ou inflada. Tabelas
wp_options,wp_postmetacom gigabytes de transients órfãos. - Latência geográfica. Servidor no Brasil + visitante na Europa = +200ms de RTT. CDN resolve.
Como melhorar TTFB
- Habilite cache full-page (WP Rocket, LiteSpeed Cache, W3 Total Cache, Cloudflare APO).
- Migre pra hosting com PHP-FPM dedicado ou serverless (Cloudways, Kinsta, WP Engine).
- Limpe transients órfãos:
DELETE FROM wp_options WHERE option_name LIKE '_transient_%'(faça backup primeiro). - Cloudflare na frente do site — caching de assets + edge cache de HTML reduz TTFB pra < 100ms.
- Audite plugins com Query Monitor — qualquer um adicionando > 50ms é candidato a remover.
Como o Radar mede
O pixel JS do Radar usa a PerformanceObserver API nativa do browser pra capturar os valores reais que o visitante experimentou — exatamente o mesmo método que o Google usa pro CrUX dataset.
- RUM (Real User Monitoring). Cada visitante real reporta seus próprios valores. Não é simulação.
- p75 por padrão. Os números mostrados no dashboard são o percentil 75 — o mesmo critério do Google ("75% dos visitantes têm score ≤ X").
- Granularidade. Por URL (Pro+), por device (mobile vs desktop, no Agency), por país.
- Histórico. Free: 7d. Starter: 30d. Pro: 90d. Agency: 180d.
- Cobertura. Web Vitals só vêm de visitantes humanos com JS habilitado — bots e visitantes sem JS não reportam métricas de browser. Isso é o esperado.
Lendo o painel Vitals do dashboard
Em /dashboard/site/<id>/v2/vitals:
- KPIs no topo — p75 atual de cada métrica com cor Good/Needs improvement/Poor.
- Time series — evolução do p75 ao longo do período selecionado. Útil pra detectar regressões depois de deploy ou de instalação de plugin novo.
- URL ranking (Pro+) — top URLs com piores vitais. É aqui que você prioriza otimização: arruma as 3 URLs com pior LCP e o p75 do site inteiro melhora.
- Long tasks — count de tasks de JS > 50ms na main thread. Indicador forte de INP problemático.
Recipes de alerta sugeridos
Em Alertas, criar regras pra ser avisado quando vitais regridem:
- LCP p75 > 4.0s por 2h consecutivas — algo quebrou (deploy, plugin novo, ataque DDoS no servidor).
- CLS p75 aumentou > 50% vs média de 7 dias — provavelmente mudança de layout (novo banner, ads).
- INP p75 > 500ms — script novo causando jank.
- TTFB p75 > 1500ms por 30min — servidor ou cache em apuros.
FAQ
Por que meu PageSpeed Insights dá outro número?
PageSpeed Insights tem dois modos:
- Field Data — vem do CrUX (visitantes reais via Chrome). É o que o Google usa pra ranking. Comparável ao Radar.
- Lab Data — Lighthouse rodando uma simulação numa máquina do Google. Não usa pra ranking. Geralmente mostra números piores que a realidade.
Use Field Data pra comparar com Radar. Diferenças pequenas (~10%) são normais porque CrUX agrega últimos 28 dias e Radar mostra o range selecionado.
E se meu site não tem visitantes humanos suficientes?
Vitals dependem de RUM. Se o site recebe < 100 visitantes humanos por dia, o p75 vai ter ruído. Use o intervalo de 30d ou 90d (Pro+) pra ter sample size maior. Alternativa: rode auditorias Lighthouse periódicas localmente como complemento — mas saiba que Lighthouse não rankeia.
FID ainda aparece em algum lugar?
Não. O Google substituiu FID por INP em março de 2024. O Radar reporta só INP, alinhado com o critério atual de ranking.
Web Vitals importam pra SEO em sites pequenos?
Importam pra qualquer site que dependa de busca orgânica. O peso de Core Web Vitals no ranking é menor que conteúdo e links, mas em SERPs disputadas pode ser desempate. E uma página lenta tem bounce rate alto, o que indiretamente afeta ranking via comportamento.
O Radar mede Vitals em conexão mobile lenta?
O Radar reporta o que o visitante real experimentou — se ele acessou de 3G, o Vital reflete isso. Não há simulação. Em mobile típico (4G urbano) os números são naturalmente piores que desktop. Compare mobile contra mobile.