O que você está tentando diagnosticar (sem voltar aos fundamentos)
Diagnosticar LCP, INP e CLS é transformar uma métrica “ruim” em uma lista curta de causas prováveis, evidências e ações. DevTools e Lighthouse se complementam: o Lighthouse dá um retrato automatizado com auditorias e oportunidades; o DevTools permite ver a linha do tempo real do carregamento, renderização e interações, atribuindo custo a recursos, scripts e mudanças de layout.
Um diagnóstico útil responde a perguntas objetivas: qual elemento foi o LCP e por quê demorou? qual interação gerou o INP e qual parte do processamento consumiu tempo? quais elementos mudaram de posição e o que disparou essas mudanças? A partir daí, você consegue priorizar correções com alto impacto.
Diagnóstico de LCP com DevTools
1) Identificar o elemento de LCP e o momento exato
No Chrome DevTools, a forma mais direta é usar o painel Performance e observar o evento de LCP na trilha de “Timings”.
- Abra a página em uma janela normal (não precisa ser anônima, mas evite extensões que alterem o DOM).
- DevTools > Performance.
- Marque Web Vitals (quando disponível) e/ou Screenshots para correlacionar visualmente.
- Clique em Record e recarregue a página (Ctrl/Cmd+R).
- Ao parar a gravação, procure na trilha de Timings um marcador de LCP. Clique nele.
Ao selecionar o marcador, o DevTools costuma mostrar detalhes do elemento (por exemplo, um <img>, um bloco de texto, um <h1> ou um background). Esse é o “candidato” que o navegador considerou como maior conteúdo visível no viewport no momento do LCP.
2) Decompor o LCP em fases (onde o tempo foi gasto)
O LCP geralmente é atrasado por uma combinação de: tempo de resposta do servidor, bloqueio de renderização por CSS/JS, prioridade/descoberta tardia do recurso (imagem/fonte), e custo de renderização (layout/paint) quando o elemento finalmente pode aparecer.
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
No DevTools, você consegue evidenciar isso com três áreas:
- Network: quando o recurso do LCP foi descoberto, quando começou a baixar e quando terminou.
- Performance: quanto tempo foi gasto em scripting, style/layout e paint antes do LCP.
- Rendering/Layer (quando necessário): se há custos de composição/pintura altos.
Passo a passo para correlacionar:
- No Performance, selecione uma janela de tempo que vai do início do carregamento até logo após o LCP.
- Observe a trilha principal (Main). Se houver longas tarefas (long tasks) antes do LCP, elas podem estar atrasando o processamento de CSS/JS e a renderização.
- Abra Network e filtre pelo recurso do elemento LCP (por nome do arquivo, tipo ou iniciador). Verifique: Start Time, TTFB, Download.
Um padrão comum: o LCP é uma imagem grande, mas ela começa a baixar tarde porque o HTML/JS só a insere depois, ou porque o navegador não a priorizou. Outro padrão: o CSS crítico chega tarde e bloqueia a renderização, então o elemento existe mas não pode ser pintado.
3) Verificar se o LCP é imagem, texto ou background (e implicações)
O tipo do elemento muda o tipo de correção:
- Imagem (
<img>): foco em prioridade, tamanho/formatos, preload e evitar lazy-load indevido acima da dobra. - Texto: foco em CSS bloqueante, carregamento de fontes e custo de renderização (ex.: CSS pesado, muitas regras, recalculations).
- Background via CSS: pode ser mais difícil de priorizar; frequentemente exige
preloade revisão de como o background é aplicado.
Como confirmar rapidamente:
- DevTools > Elements: selecione o elemento indicado no LCP (quando disponível).
- Verifique se é
<img>ou se a imagem está embackground-imageno painel de estilos.
4) Checar sinais de bloqueio por CSS e fontes
Mesmo sem repetir conceitos básicos, na prática você quer evidências de bloqueio:
- No Network, filtre por CSS e veja se há arquivos grandes chegando tarde.
- Em Performance, procure por períodos longos de Recalculate Style e Layout antes do LCP.
- No Network, filtre por Font e veja se fontes essenciais chegam tarde e se há múltiplas variações (weights) baixadas.
Se o LCP for texto e você notar fontes baixando tarde, o texto pode estar aguardando a fonte (dependendo da estratégia de carregamento). Se o LCP for imagem, mas o CSS é pesado e bloqueia a renderização, o download pode até terminar cedo, mas o paint do elemento ocorre tarde.
5) Confirmar prioridade e descoberta do recurso do LCP
Para imagens, um diagnóstico recorrente é: “a imagem do herói não foi priorizada”. Você consegue verificar isso no Network:
- Abra o recurso da imagem e observe Priority (quando a coluna estiver habilitada).
- Veja o Initiator: foi o HTML parser? foi CSS? foi um script? Se foi script, a descoberta pode ter sido tardia.
Se a imagem do LCP aparece como iniciada por um script após um bundle grande, isso é um forte indício de que o caminho crítico está atrasando a descoberta do recurso.
6) Exemplo prático: LCP atrasado por imagem descoberta tarde
Cenário: o LCP é a imagem do banner principal, mas ela só começa a baixar após a execução de um bundle.
Como você veria isso:
- No Performance, antes do LCP há uma long task de scripting.
- No Network, a imagem inicia depois dessa long task, com Initiator apontando para um script.
O diagnóstico fica: “LCP atrasado por descoberta tardia do recurso e competição com JS no main thread”. A correção típica envolve garantir que o recurso seja descoberto cedo (por HTML/CSS) e que não esteja sendo adiado por hidratação/renderização client-side.
Diagnóstico de INP com DevTools
1) Encontrar interações lentas e decompor o tempo (input, processamento, apresentação)
INP está ligado a interações reais do usuário. Em laboratório, você precisa simular interações e observar o custo no main thread. O DevTools ajuda a identificar: qual evento disparou, quanto tempo o handler executou, e quanto tempo foi gasto até o próximo frame ser apresentado.
Passo a passo no DevTools:
- DevTools > Performance.
- Clique em Record.
- Interaja com a página (clique em botões, abra menus, digite em campos, faça scroll em componentes que executam JS).
- Pare a gravação.
Agora procure por:
- Interações (quando o DevTools agrupa eventos de input) e marcadores relacionados.
- Long tasks na trilha Main durante ou logo após a interação.
- Eventos como
click,pointerdown,keydownno “Event Log” (dependendo da versão do DevTools).
2) Usar o painel Performance para achar o “culpado” no main thread
O INP ruim quase sempre aparece como: você interage, mas o main thread está ocupado (JS pesado, layout síncrono, renderização cara). O objetivo é chegar a uma função, arquivo e linha.
Passo a passo:
- Na gravação, selecione o intervalo logo após a interação (zoom na área onde o atraso é visível).
- Na trilha Main, clique na long task (barra longa amarela/roxa, dependendo do tipo).
- No painel inferior, abra a aba Bottom-Up para ver quais funções consumiram mais tempo.
- Use Call Tree para entender a cadeia de chamadas.
- Clique na função para abrir o arquivo no painel Sources.
Se o tempo estiver em “Recalculate Style” ou “Layout”, isso indica que a interação disparou mudanças no DOM/CSS que exigiram recalcular estilos e reposicionar elementos. Se estiver em scripting, você procura handlers, validações, serializações, renderizações, loops e trabalho síncrono.
3) Identificar padrões típicos que degradam INP
Durante o diagnóstico, procure por padrões recorrentes:
- Handlers muito grandes: um clique dispara várias operações (fetch + processamento + render) tudo no mesmo tick.
- Renderização excessiva: frameworks re-renderizando grandes subárvores após cada tecla.
- Leituras e escritas de layout intercaladas: medir (
offsetHeight,getBoundingClientRect) e logo depois escrever estilo repetidamente, causando layout thrashing. - JSON/parse/stringify pesado no caminho da interação.
- Bibliotecas de terceiros executando trabalho em resposta a eventos (analytics, tag managers, widgets).
4) Exemplo prático: clique em “Filtrar” trava por 400ms
Cenário: ao clicar em “Filtrar”, a UI demora a responder.
Como diagnosticar:
- Grave no Performance e clique no botão.
- Encontre a long task após o evento
click. - Em Bottom-Up, veja se o tempo está em uma função de renderização (ex.:
renderResults) ou em uma rotina de filtro (ex.:applyFilters). - Se houver muito tempo em Layout, abra o trecho e observe se o código lê layout dentro de loops.
O diagnóstico final deve ser específico: “o handler de clique executa filtragem O(n*m) e atualiza o DOM item a item, causando múltiplos layouts; isso ocupa o main thread por ~400ms e degrada a responsividade”.
5) Complemento: usar o painel Performance monitor e o painel Rendering
Para interações, às vezes é útil observar FPS e trabalho de renderização:
- DevTools > Command Menu (Ctrl/Cmd+Shift+P) > procure por Performance monitor.
- Observe CPU, JS heap, DOM nodes e FPS enquanto interage.
- Em More tools > Rendering, habilite Paint flashing para ver o que repinta ao interagir.
Se um pequeno hover repinta uma área enorme, ou se um clique dispara repaints contínuos, você tem um indício de custo de renderização que pode afetar a latência percebida e, em casos, o INP.
Diagnóstico de CLS com DevTools
1) Encontrar “Layout Shifts” e ver as causas
O DevTools oferece uma trilha específica para mudanças de layout no painel Performance. O objetivo é identificar quais elementos se moveram e qual foi o gatilho (imagem sem dimensões, inserção de banner, fonte trocando, componente expandindo etc.).
Passo a passo:
- DevTools > Performance.
- Ative Screenshots.
- Grave e recarregue a página.
- Durante o carregamento, observe a trilha Experience (ou similar) e procure por Layout Shift.
- Clique em um evento de Layout Shift.
Ao selecionar um Layout Shift, o DevTools costuma destacar visualmente as áreas que mudaram e listar os “nodes” envolvidos. Isso é ouro para diagnóstico: você deixa de “achar” e passa a “ver” o que se moveu.
2) Correlacionar o shift com a requisição ou script que o provocou
Depois de identificar o shift, você quer responder: o que aconteceu imediatamente antes?
- No Performance, com o shift selecionado, olhe alguns milissegundos antes na trilha Main: houve execução de script? houve aplicação de estilos? houve carregamento de fonte?
- No Network, verifique se algum recurso terminou de baixar naquele momento (imagem, CSS, fonte, script de terceiro).
Exemplos de correlação:
- Shift ocorre no exato momento em que uma imagem termina de baixar e é inserida sem dimensões reservadas.
- Shift ocorre quando um script injeta um banner no topo (ex.: consentimento, promoções).
- Shift ocorre quando a fonte web aplica e muda métricas do texto (troca de fonte).
3) Usar “Layout Shift Regions” para enxergar o impacto
No painel Rendering, existe a opção de destacar regiões de layout shift (o nome pode variar por versão, mas a ideia é a mesma). Isso ajuda a reproduzir e enxergar shifts que acontecem rápido.
- DevTools > More tools > Rendering.
- Habilite a visualização de Layout Shift Regions.
- Recarregue e observe as áreas destacadas quando ocorrerem shifts.
4) Exemplo prático: CLS causado por card de produto que “cresce” após carregar preço
Cenário: uma grade de produtos carrega rapidamente, mas os preços chegam depois e empurram o layout.
Como diagnosticar:
- Grave no Performance e recarregue.
- Clique no evento de Layout Shift e veja quais nós mudaram (provavelmente o container do preço e elementos abaixo).
- Volte alguns ms e veja se houve uma requisição XHR/fetch concluindo e um script atualizando o DOM.
O diagnóstico fica: “o componente renderiza sem reservar espaço para o preço/parcelamento; quando os dados chegam, o texto ocupa mais linhas e empurra os cards, gerando shifts”.
Como usar o Lighthouse para guiar o diagnóstico (e não só “tirar nota”)
1) Rodar Lighthouse e interpretar as seções relevantes
O Lighthouse é útil para apontar oportunidades e, muitas vezes, já indicar o elemento de LCP e possíveis causas. Para diagnóstico, o valor está em cruzar as auditorias com evidências no DevTools.
Passo a passo:
- DevTools > Lighthouse.
- Selecione Performance.
- Escolha o modo (Mobile/ Desktop) conforme o cenário que você quer investigar.
- Gere o relatório.
Seções para usar como mapa:
- Metrics: veja LCP e CLS reportados no lab e se há indicação de TBT (que costuma correlacionar com problemas de responsividade e pode ajudar a investigar INP).
- Diagnostics e Opportunities: itens como redução de JS, CSS não usado, imagens, preload, cache e terceiros.
- Largest Contentful Paint element: quando presente, mostra qual elemento foi LCP e dá pistas (imagem, texto, seletor).
2) Mapear auditorias do Lighthouse para verificações no DevTools
Use o Lighthouse para levantar hipóteses e o DevTools para confirmar. Alguns mapeamentos práticos:
- “Largest Contentful Paint element” → confirme no Performance o marcador de LCP e veja a timeline do recurso no Network.
- “Eliminate render-blocking resources” → no Network, veja CSS/JS no início e no Performance observe se o main thread está ocupado antes do LCP.
- “Reduce unused JavaScript” → no Performance, identifique long tasks e no Coverage (DevTools > More tools > Coverage) verifique quanto do bundle é realmente usado no carregamento inicial.
- “Properly size images / Serve images in next-gen formats” → no Network, compare tamanho transferido vs. dimensões exibidas e verifique se a imagem do LCP está superdimensionada.
- “Avoid large layout shifts” → no Performance, clique nos Layout Shifts e identifique os nós; no Rendering, habilite Layout Shift Regions para reproduzir.
3) Usar o modo “View Trace” do Lighthouse para aprofundar
O relatório do Lighthouse permite abrir o trace (rastreamento) que ele coletou. Isso é útil porque você vê a mesma linha do tempo do Performance, mas já associada ao contexto do relatório.
- No relatório, procure por uma opção como View Trace (ou abra o trace associado).
- Identifique o ponto do LCP e veja o que estava acontecendo no main thread e no network naquele momento.
Isso acelera o diagnóstico quando você quer reproduzir exatamente o cenário do Lighthouse e comparar com suas gravações manuais no Performance.
Checklist prático de diagnóstico (LCP, INP, CLS) para usar em bugs e PRs
LCP
- Qual foi o elemento de LCP (imagem/texto/background)?
- O recurso do LCP começou a baixar cedo? Quem foi o initiator?
- O download terminou cedo, mas o paint aconteceu tarde (bloqueio por CSS/JS)?
- Há long tasks antes do LCP no main thread?
- Há CSS/fontes chegando tarde que impactam o elemento?
INP
- Qual interação específica é lenta (clique, digitação, abertura de menu)?
- Há long task imediatamente após o evento?
- O tempo está em scripting (funções específicas) ou em style/layout?
- Há re-renderização grande ou loops no handler?
- Terceiros estão executando trabalho no caminho da interação?
CLS
- Quais eventos de Layout Shift aparecem no Performance?
- Quais nós mudaram (lista do DevTools) e qual região foi afetada?
- O shift coincide com carregamento de imagem, fonte, CSS ou execução de script?
- O shift é causado por inserção acima do conteúdo (banners, avisos) ou por expansão de componentes?
Snippets úteis para confirmar suspeitas durante o diagnóstico
Registrar LCP e o elemento no console (para depuração local)
new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); const last = entries[entries.length - 1]; console.log('LCP:', last.startTime, last);}).observe({ type: 'largest-contentful-paint', buffered: true });Esse snippet ajuda a confirmar o timing e inspecionar detalhes do entry em ambientes onde você consegue reproduzir localmente.
Registrar Layout Shifts e ignorar shifts com interação recente
let cls = 0;new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (!entry.hadRecentInput) { cls += entry.value; console.log('Layout shift:', entry.value, 'Total CLS:', cls, entry); } }}).observe({ type: 'layout-shift', buffered: true });Isso permite ver quais shifts contam para CLS e inspecionar o entry para entender o que se moveu.
Registrar interações e long tasks (pistas para INP)
new PerformanceObserver((list) => { for (const entry of list.getEntries()) { console.log('Long task:', entry.startTime, entry.duration, entry); }}).observe({ type: 'longtask', buffered: true });Long tasks não são INP, mas são um excelente sinal de que o main thread está ocupado e pode atrasar a resposta a interações.