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 enlace o botón equivocado. En algunos casos, esto puede causar daños graves.
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 a la página de forma dinámica antes del contenido existente. Los cambios de diseño pueden deberse a imágenes o videos con dimensiones desconocidas, fuentes que se renderizan más grandes o más pequeñas que su resguardo inicial, o anuncios o widgets de terceros que cambian su tamaño de forma dinámica.
Las diferencias entre el funcionamiento de un sitio en desarrollo y la experiencia de los usuarios empeoran este problema. Por ejemplo:
- A menudo, el contenido personalizado o de terceros se comporta de forma diferente en el desarrollo y en la producción.
- Por lo general, las imágenes de prueba ya están en la caché del navegador del desarrollador, pero el usuario final tarda más en cargarse.
- 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 midiendo la frecuencia con la que ocurre en usuarios reales.
¿Qué es CLS?
CLS es una medida del aumento de actividad más grande de puntuaciones de cambio de diseño por cada cambio de diseño inesperado que ocurre durante todo el ciclo de vida de una página.
Un cambio de diseño ocurre cada vez que un elemento visible cambia su posición de un fotograma renderizado al siguiente. Más adelante en esta guía, se explica cómo se calculan las puntuaciones de cambios 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 una sucesión rápida, 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 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.
¿Qué es una buena puntuación de CLS?
Para proporcionar una buena experiencia del usuario, los sitios deben esforzarse por tener una puntuación del 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 en dispositivos móviles y computadoras de escritorio.
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 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 las entradas layout-shift
cada vez que un elemento visible dentro del viewport cambia su posición de inicio (por ejemplo, la posición superior e izquierda en el modo de escritura predeterminado) entre dos fotogramas. Esos elementos se consideran elementos inestables.
Ten en cuenta que los cambios de diseño solo ocurren cuando los elementos existentes cambian su posición de inicio. Si se agrega un nuevo elemento al DOM o cambia de tamaño un elemento existente, no cuenta como un cambio de diseño, siempre y cuando el cambio no provoque 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 marcos renderizados. La puntuación del 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 el impacto de los elementos inestables en el área del viewport entre dos fotogramas.
La fracción del 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 del viewport en un marco. Luego, en el siguiente fotograma, el elemento se desplaza hacia abajo un 25% de la altura del viewport. El rectángulo rojo punteado indica la unión del á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 movieron los elementos inestables en relación con el viewport. La fracción de distancia es la distancia horizontal o vertical más alta que cualquier elemento inestable se movió en el marco dividida por la dimensión más grande del viewport (ancho o alto, la 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 del 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.
La opción "Click Me!" no estaba previamente en el DOM, por lo que su posición de inicio tampoco cambia.
Sin embargo, la posición inicial del cuadro verde cambia, pero como se movió parcialmente fuera del viewport, no se considera el área invisible cuando se calcula la fracción de impacto. La unión de las áreas visibles del cuadro verde en ambos marcos (ilustrado por el rectángulo rojo de puntos) es la misma que el área del cuadro verde en el primer marco (50% de la 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 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 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 para animales, ordenados alfabéticamente. En el segundo marco, se agregan más resultados a la lista ordenada.
El primer elemento de la lista ("Cat") no cambia su posición de inicio entre los fotogramas, por lo que es estable. Del mismo modo, los nuevos elementos agregados a la lista no estaban previamente en el DOM, por lo que sus posiciones iniciales tampoco cambian. Pero los elementos etiquetados como "Perro", "Caballo" y "Zebra" cambian sus posiciones de inicio, lo que los hace elementos inestables.
Nuevamente, los rectángulos rojos y punteados representan la unión de estos tres elementos inestables". áreas anteriores y posteriores, 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 desplazaron de sus posiciones iniciales. La "cebra" representado por la flecha azul, se movió más, aproximadamente 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
.
Cambios de diseño esperados versus inesperados
No todos los cambios de diseño son malos. De hecho, muchas aplicaciones web dinámicas cambian con frecuencia 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 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) son generalmente correctos, siempre que el cambio se produzca lo suficientemente cerca de la interacción para que el usuario pueda ver la relación clara.
Por ejemplo, si una interacción del usuario activa una solicitud de red que puede tardar un poco en completarse, es mejor crear un poco de 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 estará listo el recurso, es posible que intente hacer clic en otro elemento mientras espera, algo que podría salir debajo de él.
Los cambios de diseño que se produzcan dentro de los 500 milisegundos desde la entrada del usuario tendrán establecida la marca hadRecentInput
, por lo que se pueden excluir de los cálculos.
Animaciones y transiciones
Cuando se hacen 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 inesperada y abrupta 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 está sucediendo 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 con las animaciones.
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 los elementos, evita cambiar las propiedades
top
,right
,bottom
oleft
, y usatransform: translate()
en su lugar.
Cómo medir el CLS
El CLS se puede medir en el lab o en el campo y está disponible en las siguientes herramientas:
Herramientas de campo
- Experiencia del usuario en Chrome Informe
- PageSpeed Insights
- Search Console (Métricas web esenciales
- Biblioteca JavaScript
web-vitals
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 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 JavaScript de web vitals
, que contiene una implementación de referencia sobre cómo se calcula 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 para esa página, pero hay algunas excepciones importantes que se indican en la siguiente sección. La biblioteca JavaScript web vitals
los contempla 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 algún 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 la página diferente.
- La API no informa las entradas de
layout-shift
para los cambios que ocurren dentro de los iframes, pero la métrica sí, ya que forman parte de la experiencia del usuario de la página. Esto puede mostrarse como una diferencia entre CrUX y RUM. Para medir correctamente la CLS, debes tenerlas en cuenta. Los submarcos pueden usar la API para informar sus entradaslayout-shift
al marco superior con fines de agregación.
Además de estas excepciones, CLS tiene cierta complejidad adicional debido a que mide la vida útil completa de una página:
- Los usuarios pueden mantener una pestaña abierta mucho tiempo: 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 no suelen ejecutar devoluciones de llamada de descarga de páginas para las pestañas en segundo plano, lo que dificulta informar la "finalización". valor.
Para manejar estos casos, el CLS se debe informar cada vez que una página está en segundo plano, además de cada vez que se descarga (el evento visibilitychange
abarca ambas situaciones). Y los sistemas de análisis que reciben estos datos deberán calcular el valor de CLS final en el backend.
En lugar de memorizar y resolver 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 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 deseas obtener más orientación sobre cómo identificar cambios de diseño en el campo y usar datos de lab para optimizarlos, consulta nuestra guía sobre cómo optimizar 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, es necesario realizar cambios a veces, y estos pueden aparecer como mejoras o regresiones en tus informes y paneles internos.
Para ayudarte a administrar esto, todos los cambios que realices 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 al grupo de Google web-vitals-feedback.