Corrigir e Identificar Problemas de Cumulative Layout Shift (CLS)

Aprenda a encontrar e corrigir todos os problemas de Cumulative Layout Shift usando dados de RUM, Chrome DevTools e correções direcionadas de CSS e HTML

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-27

Encontrar e Corrigir Problemas de Cumulative Layout Shift (CLS)

Esta página faz parte da nossa série sobre Cumulative Layout Shift (CLS). O CLS mede a estabilidade visual da sua página rastreando o movimento inesperado do conteúdo. Uma boa pontuação de CLS é inferior a 0.1, pontuações acima de 0.25 são ruins. Se você é novo no CLS, comece pela página central do CLS para ver a fórmula, os limites e a mecânica das janelas de sessão.

O CLS é o Core Web Vitals com melhor desempenho. De acordo com o Web Almanac de 2025, 72% dos sites passam no CLS globalmente. Isso parece ótimo até você perceber que a maioria dos desenvolvedores nunca vê problemas de CLS em suas próprias máquinas. As mudanças ocorrem para visitantes de primeira viagem em conexões lentas e, quando você verifica no DevTools com seu cache aquecido, tudo parece bem. É exatamente isso que torna o CLS difícil de depurar.

Este guia é baseado no processo passo a passo exato que uso ao prestar consultoria sobre CLS. Dados do CrUX e RUM primeiro, validar no Chrome e depois escrever a correção.

Última revisão por Arjen Karel em março de 2026

DICA DE CLS: O CLS é medido em janelas de sessão, não como um total contínuo. O navegador agrupa as mudanças de layout em sessões (máximo de 5 segundos, intervalos de 1 segundo entre as mudanças) e sua pontuação de CLS é a pior sessão. Uma única explosão de mudanças durante o carregamento da página pode reprovar seu CLS, mesmo que o resto da visita seja perfeitamente estável.

Passo 1: Verificar o CLS no Search Console

Antes de alterar qualquer coisa, confirme se você realmente tem um problema de CLS. Faça login no Google Search Console, navegue até Core Web Vitals e verifique tanto dispositivos móveis quanto desktops.

Se o Google estiver sinalizando URLs com "Problema de CLS: mais de 0.25" ou "Problema de CLS: mais de 0.1", você tem a confirmação do Chrome User Experience (CrUX) Report de que usuários reais estão experimentando mudanças de layout no seu site.

Ao contrário do LCP e do INP, onde o poder de computação bruto e a velocidade da rede são importantes, os problemas de CLS podem ser específicos do dispositivo ou do tamanho da tela. Quando um problema semelhante afeta dispositivos móveis e desktops (imagens sem tamanho, trocas de fontes, conteúdo injetado), devido ao tamanho da tela, o desktop pode relatar um valor de CLS muito maior (porque uma parte maior da viewport visível pode ser afetada). O Search Console agrupa URLs, então ele informa quais tipos de página são afetados, mas não quais elementos estão mudando. Para isso, você precisa de RUM.

Google Search Console mostrando problemas de CLS do Core Web Vitals.

Passo 2: Identificar Problemas de CLS com Dados de RUM

O Search Console confirma que o problema existe, mas quase não lhe dá nada com o que trabalhar. Você precisa descobrir quais elementos estão mudando, em quais páginas e sob quais condições. Para isso, você precisa de uma ferramenta de RUM.

Eu criei o CoreDash para responder exatamente a essas perguntas. Você adiciona uma tag de script e ela começa a coletar dados de atribuição de CLS de cada visitante real. O ponto de dados principal para a depuração do CLS é o elemento em mudança: o nó do DOM real que se moveu. Sem essa informação, você está depurando às cegas.

Encontrar elementos em mudança

Comece observando seus dados de CLS agrupados por elemento. No CoreDash, navegue até a página de CLS e visualize a tabela de dados classificada por "CLS por Elemento". Isso mostra quais elementos causam a maior mudança de layout em todos os seus visitantes. Clique no pior deles para filtrar todas as métricas das páginas onde esse elemento mudou.

CoreDash mostrando pontuações de CLS divididas por elemento em mudança.

Descobrir quais páginas são afetadas

Depois de filtrar pelo elemento em mudança mais impactante, verifique a análise de URL. Problemas de CLS podem ocorrer em todo o site ou em todo o modelo. Agora sabemos se o CLS está agrupado em tipos de página específicos: páginas de produtos com galerias de imagens, postagens de blog com espaços de anúncios ou landing pages com animações hero. Saber quais páginas falham diz a você onde se concentrar.

Verificar novos visitantes vs. visitantes recorrentes

Esta é outra verificação rápida que faço e importa mais do que a maioria das pessoas pensa. O CLS de troca de fonte só acontece quando a fonte não está em cache. O CLS de imagem de width: auto só acontece quando a imagem não está no cache do navegador. Se o seu CLS for muito pior para visitantes de primeira viagem, você está lidando com uma mudança dependente de cache que você, como desenvolvedor, nunca verá em sua própria máquina a menos que desative o cache (dica: sempre desative o cache do Chrome ... mas essa é outra história para outro dia).

Verificar tipos de dispositivos e tamanhos de viewport

Geralmente, o CLS mostra um padrão de mobile/desktop diferente do LCP e do INP. Layouts responsivos podem introduzir mudanças que só aparecem em larguras e alturas de viewport específicas. Um espaço de anúncio que causou problemas no desktop pode nem estar na viewport do dispositivo móvel. Um menu de navegação pode animar de forma diferente em breakpoints menores. Agrupe seus dados de CLS por tipo de dispositivo para saber onde eles acontecem.

Passo 3: Depurar o CLS com o Chrome

Você sabe quais elementos mudam e por quê. É hora de reproduzir o problema localmente e descobrir o que o está causando.

Usar o Visualizador de Core Web Vitals

A maneira mais rápida de ver as mudanças de layout é com a extensão do Chrome Core Web Vitals Visualizer. Carregue a página, clique no ícone da extensão e recarregue. Cada mudança de layout é destacada com uma sobreposição colorida mostrando exatamente o que se moveu e o quanto. Uso isso como meu primeiro passo antes de abrir o painel Performance porque fornece uma resposta visual imediata.

Core Web Vitals Visualizer mostrando mudanças de layout destacadas na página.

Replicar as condições no Chrome e verificar as capturas de tela da rede

Os problemas de CLS costumam ser invisíveis com um cache aquecido. Abra o DevTools, desative o cache na guia Network e limite a conexão para "Slow 4G" (meu favorito, ele mostrará o CLS causado por condições de corrida). Agora clique no ícone de engrenagem e desative o cache (enquanto o DevTools estiver aberto). Isso simula as condições que seus visitantes de primeira viagem experimentam. Vá para a guia network e ative as capturas de tela. Agora recarregue a página e observe as mudanças.

Usar o painel Performance do Chrome

A maioria das mudanças de layout é fácil de detectar quando você sabe como, mas às vezes elas vão escapar de você. Esse é o momento de abrir o Chrome DevTools (Ctrl+Shift+I) e ir para o painel Performance para depuração detalhada. Pressione Ctrl+Shift+E para recarregar e gravar. Após a página carregar, role para cima e para baixo algumas vezes. Pare a gravação.

Procure a trilha "Layout Shifts". Cada mudança aparece como um bloco colorido. Clique em uma mudança para ver:

  • O nó em mudança: o elemento do DOM que se moveu
  • A pontuação da mudança: fração de impacto multiplicada pela fração de distância
  • hadRecentInput: se a entrada do usuário precedeu a mudança (cliques e toques têm um período de carência de 500ms, mas a rolagem não)

Preste atenção em quando as mudanças acontecem. Mudanças durante o carregamento da página apontam para imagens sem tamanho, trocas de fontes ou transições de CSS. Mudanças durante a rolagem apontam para animações acionadas por rolagem usando propriedades de layout.

Painel Performance do Chrome mostrando entradas de mudança de layout durante a rolagem.

Teste rápido: desativar todas as transições

As transições de CSS que animam propriedades de layout são uma causa furtiva de CLS porque elas mudam apenas durante a fase de carregamento e são difíceis de reproduzir. Cole este trecho no console, recarregue forçadamente a página com o cache desativado e compare o CLS:

document.head.insertAdjacentHTML('beforeend',
  '<style>*{transition-property:none!important}</style>');

Se o seu CLS cair após desativar as transições, você encontrou a causa. Use o guia de depuração de transição de CSS para encontrar as transições específicas responsáveis.

Medindo o CLS com a API Layout Instability

A API Layout Instability oferece acesso direto a todas as mudanças de layout em JavaScript. Esta é a mesma API que as ferramentas de RUM usam nos bastidores:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      console.log('Layout shift:', {
        value: entry.value,
        sources: entry.sources?.map(s => ({
          node: s.node,
          previousRect: s.previousRect,
          currentRect: s.currentRect
        }))
      });
    }
  }
});
observer.observe({ type: 'layout-shift', buffered: true });

O array sources mostra quais elementos se moveram. hadRecentInput filtra as mudanças esperadas de cliques e toques. Para medição em produção, use o CoreDash ou outra ferramenta de RUM.

Passo 4: Corrigir Problemas de CLS

Você sabe quais elementos mudam e por quê. É hora de corrigi-los. O CLS não tem fases sequenciais como o LCP. Em vez disso, as mudanças de layout têm categorias de causas distintas. Aqui estão as mais comuns, na ordem em que as encontro durante as auditorias.

1. Imagens, Vídeos e Iframes Sem Dimensões

Esta é a causa número um do CLS na web. O Web Almanac de 2025 relata que 62% das páginas mobile têm pelo menos uma imagem sem tamanho. A correção: sempre inclua atributos width e height nas tags <img>, <video> e <iframe>.

<img src="hero.jpg" width="800" height="450" alt="Description">

<style>
img {
    height: auto;
    max-width: 100%;
}
</style>

Fique atento ao width: auto no seu CSS. Esta única declaração substitui o cálculo da proporção do navegador e causa mudanças de layout mesmo quando você definiu a largura e a altura no HTML. Já vi isso em dezenas de sites. O desenvolvedor fez tudo certo na marcação, mas uma regra global de CSS como img { width: auto; height: auto; max-width: 100%; } desfez tudo. Para a explicação completa, consulte corrigir mudança de layout causada por imagens com dimensionamento automático. Para um guia completo cobrindo todas as causas de CLS de imagens e mídias (vídeos, iframes, direção de arte, imagens responsivas, lazy loading, placeholders), consulte Como Imagens e Mídia Causam Mudança de Layout.

2. Trocas de Fontes da Web

Quando uma fonte da web carrega e substitui a fonte fallback, a diferença de tamanho causa uma mudança de layout. O Web Almanac de 2025 mostra que apenas 11% das páginas fazem preload de fontes da web. Isso significa que a grande maioria dos sites está vulnerável ao CLS de troca de fonte.

A correção tem duas partes. Primeiro, faça com que a fonte fallback corresponda às dimensões da fonte da web usando substituições métricas:

<style>
@font-face {
    font-family: 'My Font Fallback';
    src: local('Arial');
    size-adjust: 105.2%;
    ascent-override: 93%;
    descent-override: 24%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'My Font';
    src: url('/fonts/myfont.woff2') format('woff2');
    font-display: swap;
}

body {
    font-family: 'My Font', 'My Font Fallback', sans-serif;
}
</style>

Use um Gerador de Fonte Fallback para calcular os valores de substituição corretos para seu par de fontes. Segundo, acelere a entrega: hospede suas próprias fontes, faça preload do seu arquivo de fonte crítico e use WOFF2 com subconjuntos. Para uma estratégia completa, consulte carregamento responsivo de fontes da web e garantir que o texto permaneça visível durante o carregamento da fonte da web.

3. Animações e Transições de CSS

De acordo com o Web Almanac de 2025, 40% das páginas mobile rodam animações não compostas. Elas animam propriedades como width, height, top, left, margin e padding que acionam o recálculo de layout em cada frame.

O ofensor mais comum é transition: all. Quando um desenvolvedor escreve transition: all .3s ease, cada mudança de propriedade é animada, incluindo propriedades de layout. Durante o carregamento da página, elementos em transição de seu estado sem estilo para o estado com estilo produzem mudanças de layout que ocorrem intermitentemente e são quase impossíveis de reproduzir consistentemente. Vejo esse padrão o tempo todo.

A correção: substitua propriedades que acionam o layout por outras compostas.

  • Use transform: translateY() em vez de top/bottom
  • Use transform: translateX() em vez de left/right
  • Use transform: scale() em vez de width/height
  • Use opacity em vez de visibility combinado com mudanças de altura
  • Nunca use transition: all. Especifique a propriedade exata: transition: background-color .2s ease

transform e opacity são executados inteiramente na thread do compositor e nunca acionam o layout. Para o processo completo de depuração, consulte mudança de layout causada por transições de CSS.

4. Anúncios, Embeds e Conteúdo Injetado Dinamicamente

Anúncios carregam tarde e empurram o conteúdo para baixo. Banners de consentimento de cookies aparecem e deslocam a página. Requisições AJAX injetam novo conteúdo sem reservar espaço primeiro. Estes são todos o mesmo problema: algo aparece na página que o navegador não conhecia no momento da renderização.

A correção para tudo isso é reservar espaço. Para espaços de anúncios, defina um min-height correspondente ao tamanho esperado do anúncio:

<style>
.ad-slot {
    min-height: 250px;
    contain: layout style;
}
@media (min-width: 600px) {
    .ad-slot { min-height: 90px; }
}
</style>

A declaração contain: layout style isola o contêiner do anúncio do resto da página. Para banners de cookies, use position: fixed para sobrepor em vez de empurrar o conteúdo para baixo. Para conteúdo AJAX, reserve espaço com min-height. Você não precisa de um palpite exato: uma diferença de 50px é muito menos CLS do que uma mudança de 400px sem reserva de espaço.

Para embeds de terceiros como YouTube, Google Maps e widgets de chat, use o padrão facade: mostre um placeholder estático e carregue o embed real apenas quando o usuário interagir com ele. Zero CLS, zero desperdício de recursos.

5. Mudanças de Layout Acionadas por Rolagem

Esta é a causa do CLS que o Lighthouse nunca detectará. O Lighthouse não rola a página, então as mudanças de layout acionadas por rolagem são completamente invisíveis em testes de laboratório. A única maneira de encontrá-las é com dados de RUM ou gravando um traço no painel Performance enquanto rola manualmente.

O exemplo mais comum é um cabeçalho que se oculta ao rolar, que anima a propriedade top. Aqui está a coisa que a maioria dos desenvolvedores não sabe: a rolagem não é uma entrada de exclusão na especificação Layout Instability. Cliques e toques têm um período de carência de 500ms. A rolagem não. Cada mudança de layout acionada pela rolagem conta para sua pontuação de CLS.

A correção: use transform: translateY() em vez de top para qualquer animação acionada por rolagem. O mesmo se aplica a efeitos de paralaxe, barras de navegação que encolhem e barras de progresso ligadas à rolagem. Se ele se move na rolagem, anime-o com transform. Para o passo a passo completo com exemplos em vídeo, consulte como animações acionadas por rolagem causam CLS.

Checklist de Correção Rápida

Causa do CLS Como Detectar Correção
Imagens/vídeos sem tamanho Auditoria "unsized images" do Lighthouse Adicione width e height; remova width: auto do CSS
Trocas de fontes da web RUM: CLS pior apenas na primeira visita Substituições de métrica de fonte; preload WOFF2; hospedar fontes próprias
Transições de CSS Trecho de código do console para listar todas as transições Substitua transition: all por propriedades específicas; use transform/opacity
Anúncios que carregam tarde Atribuição de RUM mostrando elementos contêiner de anúncios min-height em espaços de anúncios; contain: layout style
Banners de consentimento de cookies Pico de CLS na primeira visita; banner em dados de atribuição Use sobreposição position: fixed em vez de empurrar o conteúdo
Animações de rolagem Traço de Performance durante a rolagem; CLS de campo > CLS de laboratório Substitua top/left/height por transform

Guias Relacionados

Para uma visão geral completa de todos os Core Web Vitals, visite o hub de Core Web Vitals ou use o Ultimate Core Web Vitals Checklist para auditar todo o seu site.

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.

Seu score do Lighthouse não conta a história toda.

Seus usuários reais estão em Android com 4G. Analiso o que eles vivem de fato.

Analisar dados de campo
Corrigir e Identificar Problemas de Cumulative Layout Shift (CLS)Core Web Vitals Corrigir e Identificar Problemas de Cumulative Layout Shift (CLS)