Como Corrigir CLS (Cumulative Layout Shift)
Aprenda a identificar e eliminar mudanças de layout inesperadas que frustram usuários e prejudicam conversões.
O Que é CLS?
Cumulative Layout Shift (CLS) mede a estabilidade visual da sua página. Ele quantifica quanto o conteúdo se move inesperadamente durante o carregamento.
Exemplo clássico: Você está prestes a clicar em um botão, mas um anúncio carrega em cima e você clica no anúncio por engano. Isso é CLS ruim.
Valores de Referência:
- ✅ Bom: Menos de 0.1
- ⚠️ Precisa melhorar: 0.1 - 0.25
- ❌ Ruim: Mais de 0.25
CLS é medido em pontos de impacto, não em segundos. Quanto mais conteúdo se move e quanto maior a distância, pior o score.
Por Que CLS é Importante?
📉 Impacto em Conversões
Estudos mostram que melhorar CLS de 0.25 para 0.05 pode aumentar conversões em 10-15%. Usuários desistem quando a página é instável.
😤 Frustração do Usuário
Cliques acidentais, perda do ponto de leitura e erros de digitação causam péssima experiência e aumentam bounce rate.
🔍 SEO
CLS é fator oficial de ranking do Google desde 2021. Sites com CLS ruim ranqueiam pior.
Causas Comuns de CLS
1️⃣Imagens Sem Dimensões
Problema: Navegador não sabe quanto espaço reservar até a imagem carregar, então o conteúdo abaixo "pula" quando a imagem aparece.
❌ Ruim:
<img src="/product.jpg" alt="Produto" />✅ Bom:
<img
src="/product.jpg"
alt="Produto"
width="600"
height="400"
/>
// Ou com Next.js Image (calcula aspect ratio)
<Image
src="/product.jpg"
alt="Produto"
width={600}
height={400}
/>2️⃣Anúncios e Embeds Sem Espaço Reservado
Problema: Anúncios, vídeos do YouTube, tweets embarcados carregam depois e empurram conteúdo para baixo.
Solução - Reserve espaço:
// CSS para manter aspect ratio
.ad-container {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
background: #f0f0f0; /* placeholder */
}
.ad-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}Dica: Use min-height para anúncios de tamanho variável.
3️⃣Fontes Web (FOIT/FOUT)
Problema: Fontes customizadas causam "flash" de texto invisível (FOIT) ou texto com outra fonte (FOUT), mudando o layout.
Solução:
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap; /* ← Mostra fallback até carregar */
}
/* Ou use opcional */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: optional; /* ← Só mostra se já estiver em cache */
}Melhor ainda: Use next/font que elimina CLS automaticamente.
4️⃣Conteúdo Dinâmico Injetado
Problema: Banners, alertas ou conteúdo carregado via JavaScript aparecem e empurram conteúdo existente.
❌ Ruim:
// Injeta banner no topo, empurra tudo
document.body.insertAdjacentHTML('afterbegin', '<div>Banner</div>');✅ Bom:
// Renderiza placeholder no HTML inicial
<div id="banner-placeholder" style="height: 60px;"></div>
// Depois, popula o placeholder
document.getElementById('banner-placeholder').innerHTML = banner;5️⃣Animações e Transições
Problema: Animar propriedades que causam reflow (width, height, top, left) provoca layout shifts.
❌ Ruim (causa CLS):
.box {
transition: width 0.3s, height 0.3s;
}✅ Bom (não causa CLS):
.box {
transition: transform 0.3s, opacity 0.3s;
}
.box:hover {
transform: scale(1.1); /* Não causa reflow */
}Regra de ouro: Apenas anime transform e opacity para performance perfeita.
Checklist para Eliminar CLS
- ✓Todas as imagens têm width e height definidos (ou use Next.js Image)
- ✓Espaço reservado para anúncios e embeds antes de carregar
- ✓Fontes com font-display: swap ou opcional
- ✓Conteúdo dinâmico não injeta acima do conteúdo existente
- ✓Animações usam apenas transform e opacity
- ✓Evitar FOUC (Flash of Unstyled Content) carregando CSS crítico inline
- ✓Placeholders para carregamento de conteúdo (skeleton screens)
Como Detectar CLS
1. Chrome DevTools
- 1. Abra DevTools (F12)
- 2. Vá para a aba Performance
- 3. Marque "Web Vitals"
- 4. Clique Record e carregue a página
- 5. Veja os shifts marcados em vermelho no timeline
2. Layout Shift Regions
No DevTools:
- 1. Abra DevTools → More Tools → Rendering
- 2. Marque "Layout Shift Regions"
- 3. Recarregue a página
- 4. Áreas que se movem ficam destacadas em azul
3. CheckSpeed
Use o CheckSpeed para análise automática de CLS com identificação dos problemas e plano de ação.
Exemplo Prático: Skeleton Loading
Uma das melhores técnicas para evitar CLS é usar skeleton screens - placeholders que mantêm o layout estável durante o carregamento.
Exemplo React/Next.js:
// components/ProductCard.tsx
export function ProductCardSkeleton() {
return (
<div className="animate-pulse">
<div className="bg-gray-200 h-48 w-full rounded"></div>
<div className="mt-4 space-y-3">
<div className="h-4 bg-gray-200 rounded w-3/4"></div>
<div className="h-4 bg-gray-200 rounded w-1/2"></div>
</div>
</div>
);
}
export function ProductCard({ product }) {
return (
<div>
<img
src={product.image}
alt={product.name}
width={300}
height={200}
/>
<h3>{product.name}</h3>
<p>{product.price}</p>
</div>
);
}
// Uso
{isLoading ? <ProductCardSkeleton /> : <ProductCard product={product} />}Casos Especiais
CLS em Single Page Apps (SPAs)
SPAs têm desafios únicos com CLS durante navegação:
- Use Suspense (React) para manter layout durante transições
- Mantenha header/footer fixos durante navegação
- Pré-carregue rotas críticas
Next.js com Suspense:
import { Suspense } from 'react';
import { ProductListSkeleton } from './skeletons';
export default function ProductsPage() {
return (
<Suspense fallback={<ProductListSkeleton />}>
<ProductList />
</Suspense>
);
}Ferramentas e Recursos
Web Vitals Extension
Extensão do Chrome que mostra CLS em tempo real enquanto navega
Lighthouse CI
Teste CLS automaticamente em cada deploy
Search Console
Veja CLS de usuários reais do seu site (dados CrUX)
Conclusão
CLS é uma das métricas mais importantes para experiência do usuário. Sites com bom CLS mantêm usuários engajados, aumentam conversões e ranqueiam melhor.
As 3 regras de ouro para eliminar CLS:
- Sempre defina dimensões para imagens e embeds
- Reserve espaço antes de injetar conteúdo dinâmico
- Anime apenas transform e opacity
Seguindo essas regras, você eliminará 90% dos problemas de CLS!
Teste o CLS do Seu Site
Descubra quais elementos estão causando layout shifts no seu site e receba um plano de ação detalhado para corrigi-los.
Analisar Meu Site Gratuitamente