Los cambios de diseño inesperados pueden interrumpir la experiencia del usuario de muchas maneras, desde hacer que pierda el lugar mientras lee si el texto se mueve de repente hasta hacer que haga clic en el vínculo o botón incorrecto. En algunos casos, esto puede causar daños graves.
El movimiento inesperado del contenido de la página suele ocurrir cuando los recursos se cargan de forma asíncrona o cuando los elementos DOM se agregan de forma dinámica a la página antes del contenido existente. La causa de los cambios de diseño puede ser imágenes o videos con dimensiones desconocidas, fuentes que se renderizan más grandes o más pequeñas que su resguardo inicial, o bien anuncios o widgets de terceros que cambian de tamaño de forma dinámica.
Las diferencias entre el funcionamiento de un sitio durante el desarrollo y la forma en que lo experimentan sus usuarios empeoran este problema. Por ejemplo:
- El contenido personalizado o de terceros suele comportarse de manera diferente en desarrollo y en 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 Desplazamiento del diseño acumulativo (CLS) te ayuda a abordar este problema midiendo la frecuencia con la que ocurre en los 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 todo el ciclo de vida de una página.
Un cambio de diseño se produce cada vez que un elemento visible cambia su posición de un fotograma renderizado al siguiente. (Más adelante en esta guía, se explican los detalles sobre cómo se calculan las puntuaciones de cambio de diseño individuales).
Una ráfaga de cambios de diseño, conocida como ventana de sesión, ocurre cuando uno o más cambios de diseño individuales se producen en rápida sucesión con menos de 1 segundo entre cada cambio y un máximo de 5 segundos para la duración total de la ventana.
El aumento 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.
¿Cuál es una buena puntuación de CLS?
Para proporcionar una buena experiencia del usuario, los sitios deben esforzarse por tener una puntuación de CLS de 0.1 o menos. Para asegurarte de alcanzar este objetivo para la mayoría de los usuarios, un buen umbral para medir es el percentil 75 de las cargas de páginas, segmentadas entre los dispositivos móviles y las computadoras de escritorio.
Para obtener más información sobre la investigación y la metodología que respaldan esta recomendación, consulta Definir los umbrales de las métricas de las Métricas web esenciales.
Cambios de diseño en detalle
Los cambios de diseño se definen en la API de Layout Instability, 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 y a la izquierda en el modo de escritura predeterminado) entre dos fotogramas. Estos elementos se consideran elementos inestables.
Ten en cuenta que los cambios de diseño solo se producen cuando los elementos existentes cambian su posición inicial. Si se agrega un elemento nuevo al DOM o un elemento existente cambia de tamaño, no se cuenta como un cambio de diseño, siempre y cuando el cambio no haga 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 observa el tamaño del viewport y el movimiento de los elementos inestables en el viewport entre dos fotogramas renderizados. La puntuación de cambio de diseño es un producto de dos medidas de ese movimiento: la fracción de impacto y la fracción de distancia (ambas se definen a continuación).
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 de un fotograma determinado es una combinación de las áreas visibles de todos los elementos inestables de ese fotograma y el anterior, como una fracción del área total del viewport.
En la imagen anterior, hay un elemento que ocupa la mitad de la ventana de visualización en un fotograma. Luego, en el siguiente fotograma, el elemento se desplaza hacia abajo un 25% de la altura de la ventana de visualización. El rectángulo rojo con puntos indica la unión del área visible del elemento en ambos fotogramas, 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 la puntuación de cambio de diseño mide la distancia que se movieron los elementos inestables en relación con el viewport. La fracción de distancia es la mayor distancia horizontal o vertical que se movió cualquier elemento inestable en el fotograma dividida por la dimensión más grande del viewport (ancho o alto, lo que sea mayor).
En el ejemplo anterior, 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.
Por lo tanto, en este ejemplo, la fracción de impacto es 0.75
y la fracción de distancia es 0.25
, por lo que la puntuación de cambio de diseño es 0.75 * 0.25 = 0.1875
.
Ejemplos
En el siguiente ejemplo, se ilustra cómo agregar contenido a un elemento existente afecta la puntuación de cambio de diseño:
En este ejemplo, el cuadro gris cambia de tamaño, pero su posición inicial no cambia, por lo que no es un elemento inestable.
El botón "Haz clic en mí" no estaba en el DOM anteriormente, por lo que su posición inicial tampoco cambia.
Sin embargo, la posición inicial del cuadro verde sí cambia, pero como se movió parcialmente fuera del viewport, 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 fotogramas (ilustrada por el rectángulo rojo con puntos) es igual al área del cuadro verde en el primer fotograma: el 50% del viewport. La fracción de impacto es 0.5
.
La fracción de distancia se ilustra con la flecha púrpura. El cuadro verde se movió hacia abajo alrededor del 14% de la ventana de visualización, por lo que la fracción de distancia es 0.14
.
La puntuación de 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 del cambio de diseño de una página:
En el primer fotograma de la imagen anterior, hay cuatro resultados de una solicitud a la API de animales, ordenados alfabéticamente. En el segundo fotograma, se agregan más resultados a la lista ordenada.
El primer elemento de la lista ("Gato") no cambia su posición inicial entre fotogramas, por lo que es estable. Del mismo modo, los elementos nuevos que se agregaron a la lista no estaban en el DOM anteriormente, por lo que sus posiciones iniciales 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, los rectángulos rojos con puntos representan la unión de las áreas anteriores y posteriores de estos tres elementos inestables, 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 movieron desde sus posiciones iniciales. El elemento "Zebra", representado por la flecha azul, se movió más, alrededor de un 30% de la altura del viewport. Eso hace que la fracción de distancia en este ejemplo sea 0.3
.
La puntuación de cambio de diseño es 0.60 x 0.3 = 0.18
.
Cambios de diseño esperados frente a inesperados
No todos los cambios de diseño son negativos. De hecho, muchas aplicaciones web dinámicas cambian con frecuencia la posición inicial de los elementos de 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 se producen 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 adecuados, siempre y cuando el cambio se produzca lo suficientemente cerca de la interacción 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 tiempo en completarse, lo mejor es crear espacio de inmediato y mostrar un indicador de carga para evitar un cambio de diseño desagradable cuando se complete la solicitud. Si el usuario no se da cuenta de que se está cargando algo o no tiene idea de cuándo estará listo el recurso, es posible que intente hacer clic en otra cosa mientras espera, lo que podría desaparecer.
Los cambios de diseño que se produzcan dentro de los 500 milisegundos posteriores a la entrada del usuario tendrán establecida la marca hadRecentInput
para que se puedan excluir de los cálculos.
Animaciones y transiciones
Las animaciones y transiciones, cuando se hacen bien, son una excelente manera de actualizar el contenido de la página sin sorprender al usuario. El contenido que cambia de forma abrupta y 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 la siguiente suele ayudar al usuario a comprender mejor lo que sucede y guiarlo entre los cambios de estado.
Asegúrate de respetar la configuración del navegador prefers-reduced-motion
, ya que algunos visitantes del sitio pueden experimentar efectos negativos o problemas de atención debido a la animación.
La propiedad transform
de CSS te permite animar elementos sin activar cambios de diseño:
- En lugar de cambiar las propiedades
height
ywidth
, usatransform: scale()
. - Para mover elementos, evita cambiar las propiedades
top
,right
,bottom
oleft
y, en su lugar, usatransform: translate()
.
Cómo medir el CLS
El CLS se puede medir en el laboratorio o en el campo, y está disponible en las siguientes herramientas:
Herramientas de campo
- Informe de experiencia del usuario de Chrome
- PageSpeed Insights
- Search Console (informe de métricas web esenciales)
- Biblioteca de JavaScript de
web-vitals
Herramientas de lab
Mide los cambios de diseño en JavaScript
Para medir los cambios de diseño en JavaScript, usa la API de Layout Instability.
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 el CLS en JavaScript
Para medir el CLS en JavaScript, debes agrupar estas entradas layout-shift
inesperadas en sesiones y calcular el valor máximo de la sesión. Puedes consultar el código fuente de la biblioteca de JavaScript web vitals
, que contiene una implementación de referencia sobre cómo se calcula el CLS.
En la mayoría de los casos, el valor de CLS actual en el momento en que se descarga la página es el valor de CLS final de esa página, pero hay algunas excepciones importantes, como se indica en la siguiente sección. La biblioteca de JavaScript web vitals
las considera 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 se pone en segundo plano antes de que el navegador pinte cualquier contenido, no debería informar ningún valor de CLS.
- Si se restablece una página desde la memoria caché atrás/adelante, su valor de CLS debe restablecerse a cero, ya que los usuarios experimentan esto como una visita a una página distinta.
- La API no informa entradas de
layout-shift
para los cambios que se producen dentro de los iframes, pero la métrica sí, ya que forman parte de la experiencia del usuario en la página. Esto puede mostrarse como una diferencia entre CrUX y RUM. Para medir correctamente el CLS, debes considerarlos. Los submarcos pueden usar la API para informar sus entradaslayout-shift
al marco superior para la agregación.
Además de estas excepciones, el CLS tiene una complejidad adicional debido a que mide toda la vida útil de una página:
- Los usuarios pueden mantener una pestaña abierta durante un tiempo muy prolongado (días, semanas o meses). De hecho, es posible que un usuario nunca cierre una pestaña.
- En los sistemas operativos para dispositivos móviles, los navegadores suelen no ejecutar devoluciones de llamada de descarga de páginas para las pestañas en segundo plano, lo que dificulta informar el valor "final".
Para controlar estos casos, se debe informar el CLS cada vez que una página está en segundo plano, además de cada vez que se descarga (el evento visibilitychange
abarca ambas situaciones). Los sistemas de estadísticas que reciban estos datos deberán calcular el valor final de CLS en el backend.
En lugar de memorizar y lidiar con 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 mencionado anteriormente, excepto el caso del 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 el CLS
Para obtener más orientación sobre cómo identificar los cambios de diseño en el campo y usar los datos de lab para optimizarlos, consulta nuestra guía para optimizar el CLS.
Recursos adicionales
- Guía de Google Publisher Tag para minimizar el cambio de diseño
- Understanding Cumulative Layout Shift, de Annie Sullivan y Steve Kobes en #PerfMatters (2020)
Registro de cambios
En ocasiones, se descubren errores en las APIs que se usan para medir las métricas y, a veces, en las definiciones de las métricas. Como resultado, a veces se deben realizar cambios, y estos 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 mostrarán en este registro de cambios.
Si tienes comentarios sobre estas métricas, puedes enviarlos en el grupo de Google web-vitals-feedback.