El CLS (Cumulative Layout Shift) es la métrica de Google que mide cuánto se mueve el contenido visible mientras tu sitio carga. Si tu CLS está mal, el usuario ve un botón, intenta tocarlo, y justo en ese momento aparece un banner que mueve TODO 60 píxeles hacia abajo. Resultado: tap accidental en un anuncio o en otro link. Frustración pura. Conversión perdida.

Qué mide CLS

A diferencia de LCP e INP que se miden en milisegundos, CLS es un número sin unidad que representa la suma de cuánto y cuán violentamente se movió tu contenido. Cuanto más alto, peor.

Zonas oficiales:

  • Bueno: menos de 0.1
  • A mejorar: entre 0.1 y 0.25
  • Pobre: más de 0.25

Verificá el CLS actual de tu sitio en nuestro test de velocidad.

Por qué CLS importa tanto para conversión

Más que cualquier otra métrica, CLS impacta directo en la tasa de error de los usuarios:

  • Hacen click en un banner sin querer
  • Pierden el lugar donde estaban leyendo
  • Tocan "Cancelar" cuando querían "Confirmar"
  • Se cierra un modal porque tap accidental

Sumado al estrés visual: aumenta la tasa de rebote. La gente cierra el tab y se va.

Las 6 causas más comunes de CLS alto

1. Imágenes sin dimensiones declaradas

El error #1 históricamente. Si tu HTML tiene:

<img src="/hero.jpg">

El navegador reserva 0 espacio hasta que la imagen carga. Cuando carga, "empuja" todo lo que está debajo. CLS al cielo.

Solución: siempre declará width y height (o aspect-ratio en CSS):

<img src="/hero.jpg" width="1200" height="600" alt="...">

Los navegadores modernos usan width/height para calcular el aspect-ratio incluso si después el CSS redimensiona la imagen.

2. Iframes sin tamaño

Embeds de YouTube, Twitter, Instagram, Google Maps. Cada uno carga asíncrono y sin width/height reservados causan shifts. Solución idéntica: declarar dimensiones o usar contenedor con aspect-ratio:

.video-wrap {
  aspect-ratio: 16 / 9;
  width: 100%;
}
.video-wrap iframe {
  width: 100%;
  height: 100%;
}

3. Fuentes web que cambian de tamaño (FOUT/FOIT)

Cuando tu fuente custom carga, el texto que se mostraba con la fuente fallback se "reflowa" al tamaño nuevo. Cada vez que veas contenido text-based moviéndose en la carga, casi siempre es esto.

Soluciones:

  • Preload de la fuente crítica
  • Usá font-display: optional si no es crítica
  • Auto-host las fuentes (Google Fonts desde CDN suma latencia)
  • Si el problema es cambio de tamaño visual: usá size-adjust y ascent-override para que la fallback ocupe el mismo espacio que la final

4. Banners de cookies, popups y CTAs inyectados

El banner de cookies que aparece DESPUÉS de cargar la página y empuja contenido = CLS alto. Soluciones:

  • Reservá el espacio del banner desde el primer paint
  • Mostralo como overlay (fixed/absolute), no como bloque que empuja
  • Si tiene que ser bloque, ponelo en el HTML inicial (no inyectado por JS después)

5. Anuncios y widgets de terceros

AdSense, banners de afiliados, widgets de Twitter, embeds de Spotify. Suelen cargar después y cambian el layout.

  • Reservá el contenedor con dimensiones mínimas (min-height)
  • Si el ad no llena el espacio, dejalo vacío (mejor que un shift)
  • Posicioná abajo del fold cuando puedas

6. Lazy loaded content sin placeholder

Imágenes lazy-loaded sin reservar espacio, scroll-triggered animations que aparecen "desde la nada", contenido AJAX que se inyecta en medio del viewport.

Solución: siempre placeholder con altura conocida (skeleton, blurhash, color sólido).

Casos especiales que vemos seguido

WooCommerce / Shopify

Los catálogos de productos a veces tienen layouts que cambian cuando se carga el precio o el stock. Reservá ese espacio con CSS desde el HTML inicial.

Blogs con imágenes

El error clásico: pegar imágenes desde el editor sin width/height. Si tu CMS no las agrega automáticamente, usá un plugin que lo haga (en WordPress: WP Image Lazy Loading + dimensiones automáticas).

Sliders y carruseles

Los carruseles que cambian de altura entre slides causan CLS al rotar. Solución: forzá altura uniforme con min-height en el contenedor.

Checklist de optimización CLS

  1. Width y height declarados en TODAS las imágenes
  2. Aspect-ratio en iframes y videos
  3. Preload + font-display: swap en fuentes críticas
  4. Banner de cookies como overlay o pre-reservado
  5. Min-height en contenedores de ads
  6. Placeholders en lazy loaded content
  7. Sin inyección de contenido above-the-fold después del initial render
  8. Auditá con DevTools → Performance → Experience (te muestra cada shift)

Cómo identificar shifts específicos

En Chrome DevTools:

  1. Abrí DevTools → Performance
  2. Grabá un reload
  3. Mirá la fila "Experience" en el timeline
  4. Cada bloque rojo = un shift. Click te muestra qué elemento se movió y por qué

En PSI también marca elementos con CLS visible bajo "Diagnostics".

Cuando es invisible pero alto

A veces el CLS está alto pero "vos no notás nada". Es porque el shift sucede después de que ya leíste el contenido. PERO Google lo ve. Las causas típicas:

  • Contenido que carga al hacer scroll (lazy) y empuja
  • Comentarios que se cargan tarde y empujan el footer
  • Sidebar con widgets que se "estiran"

Estos casos son los más difíciles de diagnosticar. La extensión Web Vitals de Chrome los muestra en tiempo real.

CLS bajo es un sello de profesionalismo. Cuando un sitio NO se mueve mientras carga, el usuario lo siente "sólido" sin saber por qué.

Mantenimiento continuo

El CLS se rompe fácil: sumás un widget nuevo, instalás un plugin, cambiás un banner. Por eso conviene monitoreo continuo:

  • Search Console → Core Web Vitals: te avisa si una página entra en rojo
  • Tests mensuales con nuestra tool
  • Si tenés plan de mantenimiento con nosotros, lo monitoreamos automáticamente

Próximos pasos