O checklist definitivo do Core Web Vitals (2026)

Todas as otimizações para verificar ao melhorar o desempenho do LCP, INP e CLS

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-10-17

O checklist definitivo do Core Web Vitals

Este checklist do Core Web Vitals cobre todas as otimizações para verificar antes de um site novo entrar no ar, ao trabalhar no Largest Contentful Paint (LCP), Interaction to Next Paint (INP) ou Cumulative Layout Shift (CLS), e após qualquer grande mudança no site. Assim, você garante que as páginas fiquem rápidas e estáveis o suficiente para passar na avaliação do Core Web Vitals do Google.

Mantenho este checklist atualizado conforme aprendo coisas novas. Faltou algo? Fale comigo.

core web vitals lcp inp cls

Checklist de otimização do Core Web Vitals

Siga seção por seção, começando pela métrica que não passa no p75 no celular. Cada seção inclui o link para o guia detalhado correspondente, para você entender por que o item é importante antes de alterar qualquer coisa.

Otimize imagens

Uma imagem grande na viewport visível geralmente se torna o elemento do Largest Contentful Paint. Por isso, otimizar imagens é uma das melhores ações para o LCP. Para a estratégia completa, leia como otimizar a imagem do LCP.

  • Redimensione as imagens para o maior tamanho em que são exibidas na tela. Cada byte gasto em pixels que ninguém vê é desperdício, e imagens no tamanho correto costumam ser 50% menores ou mais sem perda visível de qualidade. Combine isso com imagens responsivas para telas menores.
  • Aplique lazy loading nas imagens abaixo da dobra. O navegador não baixa essas imagens até o visitante rolar para perto delas, liberando a largura de banda inicial para o que está na tela — o que ajuda o First Contentful Paint (FCP) e o carregamento geral. Nunca use lazy loading na imagem do LCP: o navegador espera pelo layout antes mesmo de começar o download.
  • Adicione fetchpriority="high" à imagem do LCP e só faça preload quando ela não estiver visível no HTML. Uma tag <img> no HTML já é encontrada pelo preload scanner de qualquer forma; o atributo a move para a frente da fila. O preload com <link rel="preload" as="image" fetchpriority="high"> serve para imagens de LCP definidas no CSS ou carregadas por JavaScript, que o navegador simplesmente não enxerga no HTML.
  • Defina width e height em cada imagem. Navegadores modernos usam os dois atributos para calcular a proporção antes do carregamento da imagem, reservando o espaço exato para nada se mover quando o arquivo chegar. Isso elimina uma fonte de layout shifts.
  • Use WebP ou AVIF em vez de JPEG ou PNG. Com qualidade similar, um arquivo WebP costuma ser de 25% a 34% menor que um JPEG, e o AVIF pode economizar até 50%. Um elemento <picture> com fallbacks garante compatibilidade com todos os navegadores.
  • Use lazy loading nativo e desative qualquer lazy loading por JavaScript. O atributo loading="lazy" faz o mesmo trabalho sem precisar processar e executar um script antes.
  • Adicione srcset às imagens, com o atributo sizes para controle preciso. O navegador seleciona a imagem ideal para o dispositivo e o celular deixa de baixar o arquivo feito para telas grandes de desktop.
  • Adicione decoding="async". O navegador decodifica a imagem em paralelo e continua renderizando o restante da página durante o processo.
  • Remova metadados das imagens. Dados EXIF e similares só ocupam bytes, e removê-los não afeta a qualidade da imagem. O ImageOptim e o Squoosh fazem isso manualmente, e o Sharp pode automatizar o processo no seu build.
  • Não use imagem de fundo em CSS para o elemento do LCP. O navegador encontra uma imagem de fundo no CSS bem mais tarde do que uma tag <img> no HTML. Se não houver alternativa, faça preload com uma tag <link rel="preload"> para que ela seja descoberta cedo. Saiba mais sobre o LCP resource load delay.

Otimize fontes web

Fontes web podem atrasar o First Contentful Paint, causar layout shifts e disputar a pouca largura de banda disponível no início do carregamento da página. Veja onde hospedar os arquivos no guia sobre auto-hospedagem do Google Fonts.

  • Defina font-display: swap nas regras @font-face para acelerar a primeira renderização. O navegador exibe uma fonte de fallback imediatamente e carrega a fonte web em segundo plano. Quando estiver pronta, ele faz a troca. Saiba mais sobre como garantir que o texto permaneça visível durante o carregamento de web fonts.
  • Combine font-display: optional com preload para eliminar layout shifts causados por fontes. Com optional, o navegador aguarda cerca de 100 ms pela fonte web; se ela não chegar a tempo, o fallback permanece durante toda a visualização da página e nada troca de lugar. O preload torna muito mais provável que a fonte chegue dentro dessa janela.
  • Ajuste as dimensões da fonte de fallback para baterem com as da fonte web usando descritores font-face. Configure size-adjust, ascent-override, descent-override e line-gap-override no fallback e o texto quase não se moverá na troca pela fonte web, mantendo o CLS mínimo.
  • Faça o subset das fontes apenas com os caracteres que o conteúdo usa. Uma fonte latina completa de mais de 100 KB costuma cair para menos de 20 KB após um subset correto. O Font Squirrel cria subsets online; o pyftsubset e o glyphhanger fazem isso na linha de comando.
  • Limite a quantidade de pesos e estilos de fonte. Cada peso extra adiciona de 15 a 50 KB no download. Fique em no máximo 2 fontes críticas (normalmente com preload) e 2 que carregam depois, após o primeiro render.

Otimize scripts

Scripts podem causar problemas no Interaction to Next Paint, disparar Cumulative Layout Shifts ou atrasar o Largest Contentful Paint. Mesmo um script pequeno e bem comportado no início da página disputa recursos e atrasa as métricas de renderização (LCP e FCP). Todas as alternativas estão em 14 métodos para adiar JavaScript.

  • Remova o JavaScript desnecessário. A aba Coverage no Chrome DevTools mostra o código não utilizado, e cada trecho de código morto eliminado economiza tempo de download e de main thread.
  • Priorize scripts pelo que eles fazem. Um script que faz grandes alterações na viewport visível deve ser render blocking. Scripts importantes são adiados com defer ou carregados com async, enquanto scripts secundários esperam até o navegador ficar ocioso. O guia de priorização de recursos traz a estratégia detalhada.
  • Divida o código e aplique lazy loading nas partes. Quebre bundles grandes de JavaScript em chunks menores que carregam só quando necessários, aliviando o carregamento inicial. Qualquer bundler moderno (webpack, Rollup, esbuild) divide o código automaticamente com imports dinâmicos.
  • Minifique e recompile os arquivos JavaScript sempre com ferramentas como SWC, Terser ou esbuild. Isso costuma reduzir o tamanho do arquivo de 30% a 50%.
  • Limite os scripts de terceiros. Cada um adiciona lookups de DNS, overhead de conexão e tempo de main thread. Questione se você realmente precisa dele e se há alternativa mais leve. Verifique esses scripts com frequência no painel Network do Chrome DevTools.
  • Carregue scripts de terceiros com async ou defer. Nunca dá para prever o que um terceiro fará a seguir, então jamais deixe um script externo bloquear a renderização.
  • Acompanhe o custo dos scripts de terceiros para visitantes reais. A API Long Animation Frames (LoAF) ou o CoreDash mostram o impacto deles no INP e no LCP em field data. Defina um performance budget para JavaScript de terceiros e revise-o regularmente.

Otimize estilos

Folhas de estilo bloqueiam a renderização por padrão. Toda folha de estilo no head atrasa o First Contentful Paint e aumenta o LCP element render delay. Mantenha as folhas de estilo pequenas e separadas, e ignore truques que dividem o CSS em dois. Para dicas sobre como limpar estilos não utilizados, veja como remover CSS não utilizado.

  • Minifique o CSS. Use cssnano, PostCSS ou a compressão nativa do seu pré-processador de CSS para remover espaços em branco e comentários. É gratuito, faça isso; mas a economia é de poucos kilobytes e nenhum visitante vai notar.
  • Remova o CSS que as páginas não usam. Menos CSS significa menos dados para baixar e processar. O PurgeCSS ou a aba Coverage no Chrome DevTools ajudam a encontrar CSS não utilizado. Mas faça isso no seu próprio build: deixe desativada a função de remoção de CSS não utilizado de plugins como WP Rocket, Perfmatters ou LiteSpeed, pois ela causa tantos problemas quanto o CSS crítico.
  • Não coloque CSS inline e dispense o CSS crítico. O CSS inline infla o HTML, que é o arquivo pelo qual todo o restante espera. O navegador geralmente também não consegue armazenar esse HTML em cache; cada visualização de página baixa o mesmo CSS de novo, enquanto uma folha de estilo separada vem do cache a partir da segunda página. O CSS crítico até economiza um round trip no primeiro acesso, mas o restante do CSS chega após a primeira renderização: gerando restyle, repaint e, muitas vezes, layout shift.
  • Mantenha cada folha de estilo render-blocking abaixo de cerca de 15 KB comprimida. Isso é aproximadamente o que cabe no primeiro round trip de uma nova conexão, então trate esse valor como um budget a perseguir. Um waterfall em conexão 4G lenta mostra os dois jeitos de errar: uma folha de estilo de 60 KB demora demais, e uma sequência de arquivos de 0,3 KB paga o tempo de abertura de cada requisição. Junte os arquivos minúsculos e divida ou reduza os grandes.
  • Não carregue CSS de forma assíncrona por hábito. O truque do media="print" só funciona para CSS que você tem certeza absoluta de que não é usado na primeira tela — e raramente se tem essa certeza. Separar o CSS da primeira tela do restante nada mais é que CSS crítico com outro nome.
  • Elimine todo @import do CSS. Cada um inicia uma cadeia de folhas de estilo que o navegador só consegue buscar em sequência, e o preload scanner não consegue enxergar os arquivos no final dela. Chame os arquivos pelo HTML ou junte-os no build.

Otimize resource hints

Resource hints ajudam o navegador a baixar primeiro os recursos críticos. Um arquivo com preload entra na fila e fica disponível muito antes do que ficaria sem o hint. Bem usados, os hints reduzem o LCP resource load delay; para a versão avançada, leia sobre 103 Early Hints.

  • Remova os hints de recursos desnecessários na primeira visualização. A largura de banda inicial é escassa: cada preload ou conexão que você não precisa tira recursos dos arquivos que realmente importam.
  • Faça preconnect com os domínios necessários logo no início, como uma CDN ou um provedor de fontes. O lookup de DNS, a conexão TCP e o handshake TLS ficam prontos antes da primeira requisição para aquele domínio sair. Use <link rel="preconnect" href="https://example.com"> para origens críticas de terceiros.
  • Considere dns-prefetch quando o preconnect for excessivo. O preconnect estabelece a conexão completa, enquanto <link rel="dns-prefetch"> apenas resolve o domínio com antecedência. Isso basta para um domínio que você provavelmente precisará mais tarde, quando o custo de uma conexão completa ainda não compensa.
  • Faça preload da imagem do LCP quando ela não estiver no HTML. O LCP mede quanto tempo o conteúdo principal leva para aparecer, e fazer preload do elemento do LCP move esse recurso para o início da fila. Para uma tag <img> que já está no HTML, o atributo fetchpriority="high" faz a mesma coisa sem precisar de tag adicional.
  • Faça preload de fontes críticas com <link rel="preload" as="font" type="font/woff2" crossorigin>. O navegador busca as fontes mais cedo, o texto aparece antes e a troca de fontes causa menos layout shifts.
  • Envie resource hints como 103 Early Hints sempre que puder. Com o 103, o servidor envia os hints antes que a resposta completa esteja pronta — o momento mais cedo em que o navegador pode saber de um recurso. Se o servidor não for compatível com 103, use cabeçalhos de resposta Link; se cabeçalhos também não forem opção, adicione elementos <link> ao <head> da página como fallback.
  • Faça preload de fontes antes que o CSS as descubra. Uma fonte referenciada no CSS só é encontrada depois que o CSS foi baixado e processado. Um preload no <head> do HTML elimina essa espera: a fonte carrega em paralelo, diminuindo tanto o FCP quanto o risco de layout shift.

Otimize ícones

É fácil exagerar com ícones: carregar um pacote completo para os cinco ícones que a página usa. Ícones SVG inline grandes inflam o HTML, e uma fonte de ícones frequentemente carrega milhares de glifos que você nunca usa. Otimizar ícones ajuda o LCP (menos HTML e CSS para carregar) e o CLS (espaço reservado para cada ícone).

  • Não insira ícones SVG grandes inline no HTML. Eles aumentam o tamanho do HTML, deixam a página mais lenta e o navegador não consegue colocá-los em cache isoladamente. Um sprite sheet externo em SVG geralmente oferece o melhor equilíbrio entre desempenho e flexibilidade, embora arquivos separados ou uma fonte de ícones (com cautela) também mantenham o HTML pequeno.
  • Nunca carregue um pacote grande de ícones como o Font Awesome por inteiro. O conjunto completo pode passar de 100 KB, enquanto um subset com 20 ícones fica abaixo de 5 KB. Faça um subset em uma fonte menor ou use SVGs individuais.
  • Reserve width e height para ícones, assim como nas imagens. O navegador mantém o espaço reservado e os ícones não causam layout shifts ao carregar. Defina os atributos width e height nos elementos SVG ou atribua dimensões explícitas no CSS.
  • Não faça preload nem insira inline ícones que a primeira tela não usa, garantindo que o conteúdo essencial carregue primeiro. Aplique lazy loading nos ícones abaixo da dobra.

Otimize o tempo de resposta do servidor

O tempo de resposta do servidor, medido como Time to First Byte (TTFB), antecede todas as métricas de renderização, logo um servidor lento atrasa tudo o que vem depois. Para estratégias detalhadas, consulte os guias sobre como diagnosticar problemas de TTFB e como configurar o Cloudflare para performance.

  • Escolha um provedor de hospedagem rápido, confiável e com infraestrutura sólida. Compare provedores pelo TTFB que você mesmo mede em condições reais. Os números exibidos no marketing deles são sintéticos.
  • Monitore o tempo que o código e as consultas ao banco de dados levam, e faça isso com frequência. Ferramentas de query profiling e APM apontam direto para os endpoints lentos.
  • Faça cache no navegador e no servidor para não ter que buscar novamente dados solicitados com frequência. O cache de página inteira pode reduzir o TTFB de segundos para menos de 100 ms. O guia de otimização da duração do cache traz os detalhes.
  • Renderize pequenos blocos personalizados no cliente ou na edge. A contagem do carrinho, o status de login ou uma pequena alteração no menu não devem invalidar o cache da página inteira. Mantenha o cache de página inteira e preencha esses detalhes no cliente ou via edge rendering.
  • Ajuste o servidor web: configurações de keep-alive, quantidade de worker processes, alocação de memória e valores de timeout. Um servidor mal configurado desperdiça recursos e responde mais devagar.
  • Use uma CDN (Content Delivery Network). Ela entrega o conteúdo estático a partir de edge nodes (servidores) próximos do visitante, encurtando a distância percorrida pelos dados e acelerando o carregamento para um público global. Uma CDN também costuma ser mais bem configurada que seu próprio servidor. Veja o guia sobre configurar o Cloudflare para um passo a passo prático de configuração.
  • Faça menos trabalho por requisição. Pré-calcule operações pesadas, use algoritmos eficientes e mova tudo o que não for essencial para um job em segundo plano. Depois, passe pelo ciclo de vida das requisições na aplicação mais uma vez e elimine cada etapa que não precisa estar lá.
  • Use HTTP/3. O QUIC estabelece a conexão em um único round trip, enquanto TCP com TLS exige dois ou mais, e um pacote perdido não trava as outras requisições daquela conexão. Você nota isso principalmente em redes móveis. O ganho está na conexão, portanto aparece no TTFB e, por tabela, no LCP. Um primeiro acesso muitas vezes ainda ocorre via HTTP/2, porque o navegador descobre o HTTP/3 pelo cabeçalho Alt-Svc ou por um registro DNS HTTPS. Saiba mais sobre otimização da duração da conexão.
  • Adicione cabeçalhos Server-Timing. Eles mostram quanto tempo levou cada parte do trabalho do servidor na página, permitindo ver o gargalo e focar no ponto que atrasa o Largest Contentful Paint (LCP). Eles ficam visíveis no painel Network do Chrome DevTools, e ferramentas de RUM como o CoreDash conseguem coletá-los.
  • Registre consultas lentas no banco de dados e corrija-as regularmente. Ative o log de slow queries (todo banco de dados relevante tem) e leia o registro semanalmente. Melhores índices, consultas reescritas e uma camada de cache para as mais frequentes podem reduzir bastante o TTFB.
  • Comprima arquivos de texto (HTML, CSS, JavaScript) com GZIP ou, melhor ainda, Brotli. O servidor comprime os arquivos na hora antes de enviar, e eles ficam cerca de 70% menores. O Brotli normalmente comprime de 15% a 20% melhor que o GZIP.

Otimize a interatividade

O Interaction to Next Paint (INP) mede a rapidez com que seu site responde às interações do usuário. Um INP ruim geralmente vem de long tasks em JavaScript que bloqueiam a main thread. Cada uma das três fases do INP tem um guia próprio: input delay, processing time e presentation delay.

  • Adote o padrão idle-until-urgent em scripts pesados. Tarefas críticas rodam primeiro e o JavaScript secundário espera até a main thread ficar ociosa, garantindo que a renderização e o input do usuário nunca fiquem travados atrás de um script demorado. Agende o trabalho não urgente com requestIdleCallback e, se o resultado for exigido antes, execute-o imediatamente. Saiba mais sobre otimização do processing time.
  • Divida tarefas longas fazendo yielding para a main thread. Uma long task bloqueia a main thread e a página para de responder. Divida a tarefa em partes menores e devolva o controle ao navegador entre elas para que ele possa processar um clique ou uma tecla pressionada nos intervalos. Use scheduler.yield() onde houver suporte, ou setTimeout(0). Veja o guia sobre como melhorar o INP abandonando a rolagem por JavaScript.
  • Renderize o feedback visual antes do trabalho pesado. O INP corre até a próxima renderização, então mude o estado do botão ou exiba um spinner primeiro; depois faça o yield (scheduler.yield() ou setTimeout) e execute a parte pesada depois disso. Um estilo :active ou uma transição CSS só aparece quando a main thread está livre para renderizar; um handler que mantém a thread ocupada trava a interface junto com o restante da página.
  • Defina ouvintes de scroll e touch como passivos com { passive: true }. Isso avisa ao navegador que o handler nunca chamará preventDefault(), liberando a rolagem imediata em vez de esperar pelo JavaScript. Você nota isso principalmente no celular. A rolagem em si não é uma interação que o INP mede, portanto o foco aqui é a rolagem suave, e não o número do INP.

Monitoramento do Core Web Vitals

Monitore o Core Web Vitals continuamente: é assim que você detecta uma regressão cedo e confirma se um fix funcionou como esperado. O que conta é o field data no p75; o lab data serve para descobrir a causa. Comece pelo p75 de cada métrica no celular, pelos grupos de páginas sinalizados pelo Search Console e pela tendência das últimas semanas: uma queda brusca costuma indicar um deploy, enquanto uma piora lenta e constante geralmente decorre de scripts de terceiros acumulando-se um a um.

  • Execute o Lighthouse regularmente. Ele é a ferramenta gratuita e open source do Google para encontrar problemas de performance na página. O Lighthouse não mede o Core Web Vitals como os visitantes reais vivenciam, mas é ótimo para testar e comparar o site sempre nas mesmas condições padronizadas. Uma execução comum do Lighthouse não mede o INP, já que ninguém clica em nada durante o teste; o Total Blocking Time é o mais próximo disso. Coloque o Lighthouse no seu pipeline de CI/CD para pegar regressões antes de irem para produção.
  • Consulte o histórico do CrUX regularmente. O CrUX (Chrome User Experience Report) é a base pública do Google com dados de desempenho no mundo real, e são esses os dados que o Google usa para decidir se você passa no Core Web Vitals. Cada número no CrUX é o p75 dos últimos 28 dias, portanto uma regressão se instala ao longo de semanas e um fix leva cerca de quatro semanas para aparecer por completo. O PageSpeed Insights mostra apenas os últimos 28 dias atuais; o histórico fica no CrUX Vis e na CrUX History API.
  • Configure o rastreamento por RUM. O Real User Monitoring mede quanto tempo as páginas realmente levam para seus visitantes, nas localizações e nos dispositivos deles. O Lighthouse é um teste de lab data e o CrUX fornece o p75 dos últimos 28 dias sem dizer qual elemento ou script causou o problema. O RUM preenche essa lacuna. Recomendo o CoreDash, que desenvolvi para dados detalhados de atribuição do Core Web Vitals.
  • Defina performance budgets: metas concretas por métrica no p75 no celular, por exemplo LCP abaixo de 2,5 segundos, INP abaixo de 200 ms e CLS abaixo de 0,1. Avalie essas metas regularmente para ver de imediato quais áreas precisam de atenção primeiro.
  • Segmente seus dados. Acompanhe os tipos mais valiosos de visitantes e os modelos de página separadamente, porque o restante do tráfego pode mascarar um problema que atinge apenas eles. Divida primeiro por dispositivo e template de página; velocidade de conexão e país vêm depois.

Otimize o caminho crítico de renderização

O caminho crítico de renderização reúne cada etapa executada pelo navegador para transformar HTML e CSS (e JavaScript) em pixels na tela. Um caminho mais curto significa um First Contentful Paint mais rápido e menor LCP element render delay. Veja também como evitar tamanho excessivo do DOM.

  • Minimize a quantidade de recursos críticos. Todo recurso render blocking — CSS ou JavaScript síncrono — precisa ser baixado e processado antes de o navegador conseguir renderizar. Adie scripts não essenciais e mantenha as folhas de estilo em pouca quantidade e com tamanho pequeno.
  • Acerte a ordem de carregamento: folhas de estilo primeiro, depois a imagem do LCP e as fontes usadas na primeira tela, em seguida as outras imagens acima da dobra e, por fim, os scripts com defer. O atributo fetchpriority e os hints de priorização de recursos dizem ao navegador o que mais importa.
  • Mantenha a árvore do DOM rasa. Aninhamento profundo significa mais cálculo de estilo e mais trabalho de layout. Busque no máximo 32 níveis e menos de 1.500 elementos no total sempre que puder; um DOM mais plano renderiza mais rápido e ajuda o INP presentation delay.
  • Prefira classes e IDs a tags de elementos e atributos nos seletores. Escreva .important em vez de p.important; assim o navegador tem menos coisas para verificar no casamento de estilos e recalcula estilos mais rápido.
  • Não aninhe seletores profundamente. Cada nível extra significa mais trabalho para o navegador. Reestruture o HTML para reduzir o aninhamento ou coloque uma classe mais específica próxima ao elemento, ficando em no máximo 3 níveis.
  • Use menos seletores descendentes. Um seletor como .container .content faz o navegador subir pelos ancestrais de cada elemento .content para achar o container. Uma classe direto no elemento de conteúdo faz o match mais rápido.
  • Agrupe seletores que compartilham os mesmos estilos em uma única classe ou use a convenção BEM (Block Element Modifier). Fica mais fácil de manter e o CSS diminui.

Otimize o consentimento de cookies

O GDPR e leis semelhantes exigem um banner de consentimento de cookies, mas um banner carregado sem cuidado pode atrasar o LCP, causar CLS e elevar o INP. Para mais detalhes, leia sobre como otimizar widgets de terceiros para o Core Web Vitals.

  • Renderize o banner de consentimento no servidor quando a página já for renderizada lá. Ele chega na primeira resposta HTML, o que costuma ser mais rápido que uma solução separada em JavaScript: sem requisição de rede extra e sem script para processar.
  • Carregue o script de consentimento com async em páginas em cache e considere usar fetchpriority="high" nele para que ainda seja exibido antes de qualquer interação.
  • Exiba o banner como overlay com posição fixa. Um banner inserido no topo da página empurra tudo para baixo, gerando layout shift em cada primeiro acesso. Fixado no rodapé da tela, ele fica sobre o conteúdo e nada se move.
  • Hospede os scripts e folhas de estilo do aviso de cookies no próprio servidor sempre que puder e configure o cache. Você elimina os lookups de DNS e conexões com a plataforma de gerenciamento de consentimento, mantendo o controle sobre o carregamento.

Otimize Single Page Applications

Single Page Applications (SPAs) construídas com React ou Vue têm seus próprios problemas de Core Web Vitals: a renderização no cliente atrasa tanto o FCP quanto o LCP, e a hidratação pode travar o INP.

  • Use sempre server-side rendering ou pré-renderização. Uma SPA que renderiza apenas no cliente obriga o navegador a baixar e executar todo aquele JavaScript antes que qualquer coisa fique visível. Com SSR (Next.js, Nuxt, SvelteKit) ou pré-renderização estática, você envia HTML que o navegador pode renderizar na hora.
  • Prefira pré-renderizações estáticas a dinâmicas. Uma pré-renderização estática é gerada no momento do build e servida direto de uma CDN sem qualquer processamento no servidor, o que a torna muito mais rápida do que uma gerada por requisição. Use geração estática em todas as páginas que não precisarem de dados por requisição.
  • Carregue scripts de terceiros após a hidratação. A hidratação já consome muito tempo de main thread para tornar a página interativa, e scripts de terceiros rodando no mesmo instante pioram o input delay. Adie todo script que não seja essencial até a hidratação terminar.

Evite tamanho excessivo do DOM

Um DOM grande (mais de 1.500 elementos ou profundidade acima de 32 níveis) consome mais memória, desacelera cálculos de estilo e causa reflows pesados de layout. Isso aparece no INP presentation delay e nas métricas de renderização. Veja como corrigir o tamanho excessivo do DOM.

  • Remova os elementos do DOM que você não precisa. Procure elementos wrapper que não servem para estilização nem estrutura e substitua estruturas de <div> profundamente aninhadas por HTML semântico. Listas longas podem ser virtualizadas com bibliotecas como react-window ou virtual-scroller, mantendo o DOM ativo pequeno.
  • Mantenha seletores e consultas ao DOM eficientes. Seletores CSS complexos e consultas abrangentes em JavaScript (um querySelectorAll com padrão amplo, por exemplo) ficam cada vez mais lentos conforme o DOM cresce. Use seletores de classe específicos e limite cada consulta a uma subárvore sempre que puder.
  • Use content-visibility: auto para conteúdo fora da tela. O navegador pula a renderização desses elementos até que eles entrem no campo de visão, o que pode reduzir drasticamente o trabalho inicial de renderização em páginas com seções longas.

Otimize requisições de API

Requisições de API que bloqueiam a renderização ou seguram o conteúdo prejudicam o LCP e o TTFB. Em SPAs, dados buscados no cliente são um dos motivos mais comuns para um LCP lento.

  • Faça menos requisições de API. Cada uma pesa no carregamento da página, então analise o que a primeira visualização realmente precisa e corte o resto. Batching (várias requisições combinadas em uma só) e GraphQL economizam round trips.
  • Deixe as APIs rápidas na origem. O design e a construção da API afetam diretamente a página que espera por ela. Adicione cache do lado da API para dados solicitados com frequência.
  • Faça preload de requisições críticas de API com <link rel="preload" as="fetch" crossorigin>. Assim como no preload de imagem, a requisição começa mais cedo e os dados já estão disponíveis quando a primeira renderização precisa deles. Se você omitir crossorigin, o preload não coincidirá com a chamada fetch() e o navegador baixará os dados duas vezes. O guia de priorização de recursos traz mais técnicas.

Otimize widgets de chat

Widgets de chat são uma causa comum de layout shifts e podem até atrapalhar o LCP se carregarem cedo demais. Para um passo a passo completo, leia como implementar um widget de chat com Core Web Vitals perfeito.

  • Carregue o widget de chat depois que o conteúdo principal tiver carregado. Ninguém na história da internet precisou do chat antes de carregar o conteúdo principal da página. Inicie o widget assim que o primeiro render terminar, com requestIdleCallback ou quando o visitante rolar a página.
  • Mantenha o widget de chat oculto até que esteja pronto. Se ele causar layout shift, segure-o em opacity: 0 até completar a renderização. Assim, ele se ajusta em segundo plano sem mover conteúdo visível. Depois, faça um fade in com uma transição CSS.
  • Pesquise widgets de chat leves antes de contratar. Alguns causam bem menos problemas no Core Web Vitals que outros. Antes de se comprometer, compare o tamanho do bundle de JavaScript, o número de requisições de rede e o impacto no INP de cada fornecedor.

Otimize o desempenho de service workers

Um service worker pode acelerar bastante as visitas recorrentes ao armazenar assets e até páginas inteiras em cache, o que reduz o TTFB para visitantes que retornam. Se for mal implementado, ele deixa a navegação mais lenta. Saiba mais sobre otimização da duração do cache.

  • Armazene assets críticos no service worker. Uma estratégia cache-first para assets estáticos (CSS, JavaScript, fontes, imagens) permite que visitantes que retornam carreguem o site quase instantaneamente pelo cache local. Faça precache dos recursos mais importantes no evento install.
  • Mantenha o código do service worker enxuto. Lógica de roteamento complexa, uso pesado de event.waitUntil() e um manifesto de precache grande demais atrasam a instalação. Para recursos que mudam com frequência mas não precisam estar atualizados no exato segundo em que mudam, use stale-while-revalidate.

Otimize conteúdo em vídeo

Um vídeo se torna o elemento do LCP quando é o maior conteúdo visível na viewport. Além disso, um arquivo grande rouba largura de banda de outros recursos críticos.

  • Comprima seus vídeos com um codec moderno (H.264, VP9 ou AV1) em uma configuração sensata de qualidade. Codifique no tamanho em que o vídeo é exibido: um vídeo que aparece com 400px de largura não precisa ter 1920px. O encoding em dois passos (two-pass) oferece a melhor qualidade para o tamanho do arquivo.
  • Aplique lazy loading em vídeos abaixo da dobra. Use loading="lazy" em um <iframe> ou segure o vídeo com a API Intersection Observer. Substitua vídeos de fundo com autoplay por uma imagem de poster e carregue o vídeo apenas quando o visitante rolar para perto dele.
  • Hospede vídeos em uma CDN rápida. Arquivos de vídeo são grandes e ganham muito com a distribuição por CDN. Uma CDN dedicada para vídeos ou um serviço especializado de hospedagem (Cloudflare Stream, Mux, Bunny.net) acrescenta streaming com bitrate adaptativo, distribuição geográfica e entrega otimizada.
  • Sempre defina o atributo poster em elementos <video>. O navegador pode renderizar o poster imediatamente enquanto o vídeo carrega. Como o poster pode ser o elemento do LCP, otimize-o como qualquer outra imagem do LCP.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Escrevo código, não relatório.

Entro no seu time por 1 ou 2 sprints. Monto o monitoramento e garanto que o time mantém as métricas no verde depois que eu saio.

Entra em contato
O checklist definitivo do Core Web Vitals (2026) Core Web Vitals O checklist definitivo do Core Web Vitals (2026)