Cumulative Layout Shift (CLS)

Navegadores compatibles

  • 77
  • 79
  • x
  • x

Origen

El Cambio de diseño acumulado (CLS) es una métrica de Métricas web esenciales estable. Es una métrica importante centrada en el usuario para medir la estabilidad visual porque ayuda a cuantificar la frecuencia con la que los usuarios experimentan cambios de diseño inesperados. Un CLS bajo ayuda a garantizar que la página sea agradable.

Los cambios de diseño inesperados pueden interrumpir la experiencia del usuario de muchas maneras, desde hacer que pierdan su lugar mientras leen si el texto se mueve repentinamente hasta hacer que hagan clic en el vínculo o botón incorrecto. En algunos casos, esto puede causar daños graves.

Un cambio repentino en el diseño hace que el usuario confirme un pedido grande que pretendía cancelar.

Por lo general, el movimiento inesperado del contenido de la página ocurre cuando los recursos se cargan de forma asíncrona o cuando se agregan elementos del DOM de forma dinámica a la página antes que el contenido existente. La causa del movimiento puede ser una imagen o un video con dimensiones desconocidas, una fuente que se renderiza más grande o más pequeña que su resguardo, o un anuncio o widget de terceros que cambia de tamaño de manera dinámica.

Las diferencias entre el funcionamiento de un sitio en desarrollo y la manera en que los usuarios lo experimentan empeoran este problema. Por ejemplo:

  • El contenido personalizado o de terceros suele comportarse de forma diferente en el desarrollo y en la producción.
  • A menudo, las imágenes de prueba ya están en la caché del navegador del desarrollador, pero tardan más en cargarse para el usuario final.
  • Las llamadas a la API que se ejecutan de forma local suelen ser tan rápidas que los retrasos imperceptibles en el desarrollo pueden volverse sustanciales en la producción.

La métrica Cambio de diseño acumulado (CLS) te ayuda a abordar este problema, ya que mide la frecuencia con la que ocurre en usuarios reales.

¿Qué es CLS?

El CLS es una medida del aumento de actividad más grande de las puntuaciones de cambio de diseño para cada cambio de diseño inesperado que ocurre durante la vida útil de una página.

Un cambio de diseño se produce cada vez que un elemento visible cambia su posición de un marco renderizado al siguiente. Consulta Puntuación de cambio de diseño para obtener detalles sobre cómo se miden estos cambios.

Un aumento de actividad de cambios de diseño, conocido como ventana de sesión, ocurre cuando se producen uno o más cambios de diseño individuales en una sucesión rápida, con menos de 1 segundo entre cada cambio, durante un período máximo de 5 segundos.

El aumento de actividad más grande es la ventana de sesión con la puntuación acumulativa máxima de todos los cambios de diseño dentro de esa ventana.

Ejemplo de ventanas de sesión. Las barras azules representan las puntuaciones de cada cambio de diseño individual.

¿Qué es una buena puntuación de CLS?

Para proporcionar una buena experiencia del usuario, un sitio debe tener una puntuación CLS de 0.1 o menos. A fin de asegurarte de alcanzar este objetivo para la mayoría de los usuarios, te recomendamos medir el percentil 75 de las cargas de páginas, segmentadas entre dispositivos móviles y de escritorio.

Los valores de CLS buenos son 0.1 o menos, los valores malos son mayores que 0.25 y cualquier valor intermedio debe mejorarse
Los valores de CLS correctos son 0.1 o menos. Los valores malos son mayores que 0.25.

Para obtener más información sobre la investigación y la metodología detrás de esta recomendación, consulta Define los umbrales de las métricas web esenciales.

El diseño cambia en detalle

Los cambios de diseño se definen mediante la API de inestabilidad de diseño, que informa entradas layout-shift cada vez que un elemento visible dentro del viewport cambia su posición inicial (por ejemplo, su posición superior e izquierda en el modo de escritura predeterminado) entre dos fotogramas. Los elementos cuyas posiciones de inicio cambian se consideran elementos inestables.

Los cambios de diseño solo ocurren cuando los elementos existentes cambian su posición inicial. Si se agrega un nuevo elemento al DOM o si se modifica el tamaño de un elemento existente, solo se considerará un cambio de diseño si el cambio hace que otros elementos visibles cambien su posición inicial.

Puntuación de cambio de diseño

Para calcular la puntuación de cambio de diseño, el navegador tiene en cuenta el tamaño del viewport y el movimiento de los elementos inestables en el viewport entre dos marcos renderizados. La puntuación de cambio de diseño es el producto de dos medidas de ese movimiento: la fracción de impacto y la fracción de distancia.

layout shift score = impact fraction * distance fraction

Fracción de impacto

La fracción de impacto mide cómo los elementos inestables afectan el área del viewport entre dos fotogramas.

La fracción de impacto para un fotograma determinado es una combinación de las áreas visibles de todos los elementos inestables de ese marco y el anterior, como una fracción del área total del viewport.

Ejemplo de la fracción de impacto con un elemento inestable
Si un elemento cambia de posición, su posición anterior y actual contribuyen a su fracción de impacto.

En esta imagen, se muestra un elemento que ocupa la mitad del viewport en un fotograma. En el siguiente fotograma, el elemento se desplaza hacia abajo un 25% de la altura del viewport. El rectángulo rojo punteado indica el área visible del elemento en ambos marcos, que, en este caso, es el 75% del viewport total, por lo que su fracción de impacto es 0.75.

Fracción de distancia

La otra parte de la ecuación de puntuación de cambio de diseño mide la distancia que se mueven los elementos inestables en relación con el viewport. La fracción de distancia es la mayor distancia horizontal o vertical que cualquier elemento inestable se movió en el marco dividida por la dimensión más grande del viewport (ancho o alto, el que sea mayor).

Ejemplo de fracción de distancia con un elemento inestable
La fracción de distancia mide qué tan lejos se movió un elemento en el viewport.

En este ejemplo, la dimensión más grande del viewport es la altura, y el elemento inestable se movió un 25% de la altura del viewport, lo que hace que la fracción de distancia sea 0.25.

Una fracción de impacto de 0.75 y una fracción de distancia de 0.25 producen una puntuación de cambio de diseño de 0.75 * 0.25 = 0.1875.

Ejemplos

En el siguiente ejemplo, se muestra cómo agregar contenido a un elemento existente afecta la puntuación del cambio de diseño:

Ejemplo de cambio de diseño con varios _elementos inestables y estables_
Cuando agregas un botón en la parte inferior del cuadro gris, el cuadro verde se empuja hacia abajo y parcialmente fuera del viewport.

En este ejemplo, el cuadro gris cambia de tamaño, pero su posición de inicio no cambia, por lo que no es un elemento inestable.

El botón "Click Me!" no estaba en el DOM anteriormente, por lo que su posición de inicio tampoco cambia.

La posición inicial del cuadro verde cambia, pero se movió parcialmente fuera del viewport, y el área invisible no se considera cuando se calcula la fracción de impacto. La unión de las áreas visibles del cuadro verde en ambos marcos (el rectángulo rojo de puntos) es la misma que el área del cuadro verde en el primer marco, es decir, el 50% del viewport. La fracción de impacto es 0.5.

La fracción de distancia se ilustra con la flecha azul. El cuadro verde se desplazó hacia abajo aproximadamente un 14% del viewport, por lo que la fracción de distancia es 0.14.

La puntuación del cambio de diseño es 0.5 x 0.14 = 0.07.

En el siguiente ejemplo, se muestra cómo varios elementos inestables afectan la puntuación de cambio de diseño de una página:

Ejemplo de cambio de diseño con _elementos inestables_ y estables_ y recorte de viewport
A medida que aparezcan más nombres en esta lista, los existentes se moverán para conservar el orden alfabético.

El primer elemento de la lista ("Cat") no cambia su posición de inicio entre marcos, por lo que es estable. Los elementos nuevos que se agregaron a la lista no estaban antes en el DOM, por lo que sus posiciones de inicio tampoco cambian. Sin embargo, los elementos etiquetados como "Perro", "Caballo" y "Zebra" cambian sus posiciones iniciales, lo que los convierte en elementos inestables.

Una vez más, el rectángulo rojo punteado representa el área de estos tres elementos inestables antes y después del cambio, que en este caso es alrededor del 60% del área del viewport (fracción de impacto de 0.60).

Las flechas representan las distancias que los elementos inestables se han movido desde sus posiciones iniciales. El elemento "Zebra", representado por la flecha azul, se movió más, aproximadamente en un 30% de la altura del viewport. Eso hace que la fracción de distancia de este ejemplo sea 0.3.

La puntuación del cambio de diseño es 0.60 x 0.3 = 0.18.

Comparación entre los cambios de diseño esperados y los inesperados

No todos los cambios de diseño son malos. De hecho, muchas aplicaciones web dinámicas con frecuencia cambian la posición de inicio de los elementos en la página. Un cambio de diseño solo es malo si el usuario no lo espera.

Cambios de diseño iniciados por el usuario

Los cambios de diseño que ocurren en respuesta a las interacciones del usuario (como hacer clic o presionar un vínculo, presionar un botón o escribir en un cuadro de búsqueda) suelen ser correctos, siempre que el cambio se produzca lo suficientemente cerca de la interacción como para que la relación sea clara para el usuario.

Por ejemplo, si una interacción del usuario activa una solicitud de red que puede tardar un poco en completarse, es mejor crear espacio de inmediato y mostrar un indicador de carga para evitar un cambio de diseño desagradable cuando se completa la solicitud. Si el usuario no se da cuenta de que algo se está cargando o no tiene una idea de cuándo el recurso estará listo, puede intentar hacer clic en otro elemento mientras espera y es posible que ese otro elemento se salga de él cuando el primero termine de cargarse.

Los cambios de diseño que se produzcan en un plazo de 500 milisegundos desde la entrada del usuario tendrán configurada la marca hadRecentInput para que puedas excluirlos de los cálculos.

Animaciones y transiciones

Cuando se usan bien, las animaciones y transiciones son una excelente manera de actualizar el contenido de la página sin sorprender al usuario. El contenido que cambia de forma abrupta e inesperada en la página casi siempre crea una mala experiencia del usuario. Sin embargo, el contenido que se mueve de forma gradual y natural de una posición a otra a menudo puede ayudar al usuario a comprender mejor lo que sucede y guiarlo entre cambios de estado.

Asegúrate de respetar la configuración del navegador prefers-reduced-motion, ya que la animación puede causar problemas de salud o atención para algunos visitantes del sitio.

La propiedad transform de CSS te permite animar elementos sin activar cambios de diseño:

  • Usa transform: scale() en lugar de cambiar las propiedades height y width.
  • Para mover los elementos, usa transform: translate() en lugar de cambiar las propiedades top, right, bottom o left.

Cómo medir la métrica CLS

CLS se puede medir en el lab o en el campo, y está disponible en las siguientes herramientas.

Herramientas de campo

Herramientas del lab

Cómo medir los cambios de diseño en JavaScript

Para medir los cambios de diseño en JavaScript, usa la API de inestabilidad de diseño.

En el siguiente ejemplo, se muestra cómo crear un PerformanceObserver para registrar entradas de layout-shift en la consola:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout shift:', entry);
  }
}).observe({type: 'layout-shift', buffered: true});

Mide la CLS en JavaScript

Para medir el CLS en JavaScript, agrupa las entradas layout-shift inesperadas que accediste a las sesiones y calcula el valor máximo de la sesión. Para obtener una implementación de referencia, consulta el código fuente de la biblioteca de JavaScript web vitals.

En la mayoría de los casos, el valor CLS en el momento en que se descarga la página es el valor final de CLS para esa página, pero hay algunas excepciones importantes que se enumeran en la siguiente sección. La biblioteca web vitals de JavaScript considera estos valores tanto como sea posible, dentro de las limitaciones de las APIs web.

Diferencias entre la métrica y la API

  • Si una página se carga en segundo plano, o si lo hace antes de que el navegador pinte contenido, no se debería informar ningún valor de CLS.
  • Si se restablece una página desde la caché de atrás o adelante, su valor de CLS debe restablecerse a cero, ya que los usuarios experimentan esta situación como una visita a una página diferente.
  • La API no informa entradas layout-shift para los cambios que ocurren dentro de los iframes, pero la métrica sí porque forman parte de la experiencia del usuario de la página. Esto puede mostrarse como una diferencia entre CrUX y RUM. Para medir CLS correctamente, debes incluir iframes. Los submarcos pueden usar la API para informar sus entradas layout-shift al marco superior para la agregación.

Además de estas excepciones, CLS tiene aún más complejidad porque mide toda la vida útil de una página:

  • Los usuarios pueden mantener una pestaña abierta durante mucho tiempo, por ejemplo, días, semanas o incluso meses. De hecho, es posible que un usuario nunca cierre una pestaña.
  • En los sistemas operativos para dispositivos móviles, los navegadores no suelen ejecutar devoluciones de llamada de descarga de páginas para las pestañas en segundo plano, lo que dificulta informar el valor "final".

Para manejar estos casos, recomendamos que tu sistema informe el CLS cada vez que una página esté en segundo plano, además de cada vez que se descargue. El evento visibilitychange abarca ambas situaciones. Los sistemas de estadísticas que reciben estos datos deberán calcular el valor final de CLS en el backend.

En lugar de memorizar y analizar todos estos casos por tu cuenta, los desarrolladores pueden usar la biblioteca de JavaScript web-vitals para medir el CLS, que tiene en cuenta todo lo que se menciona aquí, excepto el caso de iframe:

import {onCLS} from 'web-vitals';

// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);

Cómo mejorar CLS

Si quieres obtener más orientación para identificar cambios de diseño en el campo y usar datos de lab para optimizarlos, consulta nuestra guía sobre optimización de CLS.

Recursos adicionales

Registro de cambios

Ocasionalmente, se detectan errores en las APIs que se usan para medir métricas y, a veces, en las definiciones de las métricas en sí. Como resultado, a veces se deben realizar cambios, que pueden aparecer como mejoras o regresiones en tus informes y paneles internos.

Para ayudarte a administrar esto, todos los cambios en la implementación o definición de estas métricas se muestran en este Registro de cambios.

Si tienes comentarios sobre estas métricas, envíalos en el grupo de Google web-vitals-feedback.