Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS)

Actualizado
Appears in: Web Vitals|Métricas

Término clave: Cumulative Layout Shift: Cambio Acumulativo del diseño (CLS) 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 .

¿Alguna vez ha leído un artículo en línea cuando algo cambia repentinamente en la página? Sin previo aviso, el texto se mueve y perdiste tu lugar. O incluso peor: estás a punto de pulsar un enlace o un botón, pero en el instante antes de que aterrice su dedo, BOOM, ¡el enlace se mueve y termina haciendo clic en algo más!

La mayoría de las veces, este tipo de experiencias son simplemente molestas, pero en algunos casos, pueden causar un daño real.

Un screencast que ilustra cómo la inestabilidad del diseño puede afectar negativamente a los usuarios.

El desplazamiento inesperado del contenido de una página generalmente ocurre porque los recursos se cargan de forma asincrónica o los elementos DOM se agregan dinámicamente a la página por encima del contenido actual. El culpable puede ser una imagen o un video con dimensiones desconocidas, una fuente que se muestra más grande o más pequeña que su alternativa, o un anuncio o widget de terceros que cambia de tamaño de forma dinámica.

Lo que provoca que este asunto sea aún más problemático es que el funcionamiento de un sitio en desarrollo suele ser bastante diferente de cómo lo experimentan los usuarios. El contenido personalizado o de terceros con frecuencia no se comporta de la misma manera en el desarrollo que en la producción, las imágenes de prueba a menudo ya están en la caché del navegador del desarrollador y las llamadas a la API que se ejecutan localmente frecuentemente son tan rápidas que el retraso no se nota.

La métrica Cumulative Layout Shift (CLS) lo ayuda a abordar este problema al medir la frecuencia con la que ocurre para los usuarios reales.

¿Qué es CLS? #

CLS es una medida de la ráfaga más grande de las puntuaciones de cambio de diseño para cada cambio de diseño inesperado que se produce durante toda la vida útil de una página.

Se produce un cambio de diseño cada vez que un elemento visible cambia su posición de un fotograma renderizado al siguiente. (Consulte más abajo para obtener más información 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, es cuando uno o más cambios de diseño individuales ocurren en rápida sucesión con menos de 1 segundo entre cada turno y un máximo de 5 segundos para la duración total de la ventana.

La ráfaga más grande es la ventana de sesión con la puntuación acumulada 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.

Precaución: Anteriormente, CLS medía la suma total de todas las puntuaciones de cambio de diseño individuales que se producían durante toda la vida útil de la página. Para ver qué herramientas aún brindan la capacidad de comparar con la implementación original, consulte Evolución del cambio de diseño acumulativo en las herramientas web .

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

Para proporcionar una buena experiencia de usuario, los sitios deben esforzarse por tener una puntuación CLS de 0.1 o menos. Para asegurarse de que está alcanzando este objetivo para la mayoría de sus usuarios, un buen umbral para medir es el percentil 75 de cargas de página, segmentado en dispositivos móviles y de escritorio.

Los valores de CLS buenos son inferiores a 0,1, los valores deficientes son superiores a 0,25 y cualquier valor intermedio debe mejorarse

Para obtener más información sobre la investigación y la metodología detrás de esta recomendación, consulte: Definición de los umbrales de las métricas de Core Web Vitals

Cambios de diseño en detalle #

Los cambios de diseño se definen mediante la API de inestabilidad de diseño, que informa las entradas de layout-shift cada vez que un elemento visible dentro de la ventana gráfica cambia su posición de inicio (por ejemplo, la parte superior y la posición izquierda en el modo de escritura predeterminado) entre dos fotogramas. Estos elementos se consideran elementos inestables.

Tenga en cuenta que los cambios de diseño solo ocurren cuando los elementos actuales cambian su posición inicial. Si se agrega un nuevo elemento al DOM o un elemento existente cambia de tamaño, no cuenta como un cambio de diseño, siempre que 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 de la ventana de visualización y el desplazamiento de los elementos inestables en la ventana de visualización entre dos fotogramas renderizados. La puntuación de cambio de diseño es un producto de dos medidas de ese desplazamiento: 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 impactan el área de la ventana de visualización entre dos marcos.

La unión de las áreas visibles de todos los elementos inestables para el fotograma anterior y el fotograma actual, como una fracción del área total de la ventana de visualización, es la fracción de impacto para el fotograma actual.

Ejemplo de fracción de impacto con un *elemento inestable*

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

Fracción de distancia #

La otra parte de la ecuación para la puntuación de cambio de diseño mide la distancia de desplazamiento en los elementos inestables, relacionadas con la ventana de visualización. La fracción de distancia es la distancia más grande que cualquier elemento inestable se ha desplazado en el marco (ya sea de forma horizontal o vertical) dividida por la mayor dimensión de la ventana de visualización (ancho o alto, el que sea mayor).

Ejemplo de fracción de distancia con un *elemento inestable*

En el ejemplo anterior, la dimensión más grande de la ventana de visualización es la altura, y el elemento inestable que se desplazó un 25% de la altura de la ventana, lo que hace que la fracción de distancia sea 0.25.

Entonces, 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 .

Inicialmente, la puntuación de cambio de diseño se calculó solo basado en la fracción de impacto. La fracción de distancia se introdujo para evitar penalizar excesivamente los casos en los que los elementos grandes se desplazan en una pequeña cantidad.

El siguiente ejemplo ilustra cómo la adición de contenido a un elemento existente afecta la puntuación de cambio de diseño:

Ejemplo de cambio de diseño con *elementos inestables* y estables y un recorte en la ventana de visualización

El botón "¡Haz clic en mí!" se adjunta a la parte inferior de la casilla gris con texto negro, lo que empuja el cuadro verde con texto blanco hacia abajo (y parcialmente fuera de la ventana de visualización).

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 previamente en el DOM, por lo que su posición de inicio tampoco cambia.

Sin embargo, la posición inicial de la casilla verde cambia, pero como se desplazó parcialmente fuera de la ventana de visualización, el área invisible no se considera al calcular la fracción de impacto. La unión de las áreas visibles para la casilla verde en ambos marcos (ilustrada por el rectángulo punteado rojo) es la misma que el área de la casilla verde en el primer marco: 50% de la ventana de visualización. La fracción de impacto es 0.5.

La fracción de distancia se ilustra con la flecha violeta. La casilla verde se desplazó hacia abajo en aproximadamente un 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 .

Este último ejemplo ilustra varios elementos inestables :

Ejemplo de cambio de diseño con varios *elementos inestables* y estables

En el primer marco de arriba, hay cuatro resultados de una solicitud de una API para animales, ordenados en orden alfabético. 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 inicial entre marcos, por lo que es estable. De manera similar, 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 "Cebra" cambian sus posiciones iniciales, lo que los convierte en elementos inestables .

Nuevamente, los rectángulos de puntos rojos representan la unión de las áreas que estaban antes y después de estos tres elementos inestables, que en este caso es alrededor del 38 % del área de la ventana de visualización (fracción de 0.38).

Las flechas representan las distancias que los elementos inestables se desplazaron desde sus posiciones iniciales. El elemento "Cebra", representado por la flecha azul, es el que más se desplazó, aproximadamente un 30% en la altura de la ventana de visualización. Eso hace que la fracción de distancia en este ejemplo sea 0.3.

La puntuación de cambio de diseño es 0.38 x 0.3 = 0.1172 .

Cambios de diseño esperados frente a inesperados #

No todos los cambios de diseño son malos. De hecho, muchas aplicaciones web dinámicas cambian con frecuencia la posición inicial de los elementos en sus páginas.

Cambios de diseño iniciados por el usuario #

Un cambio de diseño solo es malo si el usuario no lo espera. Por otro lado, los cambios de diseño que ocurren en respuesta a las interacciones del usuario (hacer clic en un enlace, pulsar un botón, escribir en una casilla de búsqueda y otros casos similares) generalmente son correctos, siempre que el cambio se produzca lo suficientemente cerca de la interacción como para que la relación sea correcta. claro para el usuario.

Por ejemplo, si la interacción de un usuario desencadena una solicitud de red que puede tardar un tiempo en completarse, es mejor crear algo de 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 algo se está cargando, o no tiene una idea de cuándo estará listo el recurso, puede intentar hacer clic en otra cosa mientras espera, algo que podría moverse de debajo de él.

Los cambios de diseño que ocurren después de 500 milisegundos desde que inició la entrada del usuario tendrán la marca hadRecentInput configurada, por lo que se pueden excluir de los cálculos.

Precaución: La marca hadRecentInput solo será verdadera para eventos de entrada discretos como pulsar, hacer clic o presionar una tecla. Las interacciones continuas, como desplazamientos, arrastres o dar toques y acercar, no se consideran "entradas recientes". Consulte la Especificación de inestabilidad de diseños para obtener más información.

Animaciones y transiciones #

Las animaciones y las 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 abrupta e inesperadamente en la página casi siempre crea una mala experiencia de usuario. Pero el contenido que se mueve de forma gradual y natural de una posición a la siguiente con frecuencia puede ayudar al usuario a comprender mejor lo que está sucediendo y guiarlo entre los cambios de estado.

CSS transform le permite animar elementos sin activar cambios de diseño:

  • En vez de cambiar las propiedades de height y width utilice transform: scale().
  • Para desplazar elementos, evite cambiar las top, right, bottom o left y en vez de eso utilice transform: translate().

Cómo medir CLS #

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

Precaución: Las herramientas de laboratorio generalmente cargan páginas en un entorno sintético y, por lo tanto, solo pueden medir los cambios de diseño que ocurren durante la carga de la página. Como resultado, los valores de CLS informados por las herramientas de laboratorio para una página determinada pueden ser inferiores a los que experimentan los usuarios reales en el campo.

Herramientas de campo #

Herramientas de laboratorio #

Medir CLS en JavaScript #

Para medir CLS en JavaScript, puede utilizar la API de inestabilidad de diseño . El siguiente ejemplo muestra cómo crear un PerformanceObserver que atiende las entradas inesperadas de layout-shift, las agrupa en sesiones y registra el valor máximo de la sesión cada vez que cambia.

let clsValue = 0;
let clsEntries = [];

let sessionValue = 0;
let sessionEntries = [];

new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
// Only count layout shifts without recent user input.
if (!entry.hadRecentInput) {
const firstSessionEntry = sessionEntries[0];
const lastSessionEntry = sessionEntries[sessionEntries.length - 1];

// If the entry occurred less than 1 second after the previous entry and
// less than 5 seconds after the first entry in the session, include the
// entry in the current session. Otherwise, start a new session.
if (sessionValue &&
entry.startTime - lastSessionEntry.startTime < 1000 &&
entry.startTime - firstSessionEntry.startTime < 5000) {
sessionValue += entry.value;
sessionEntries.push(entry);
} else {
sessionValue = entry.value;
sessionEntries = [entry];
}

// If the current session value is larger than the current CLS value,
// update CLS and the entries contributing to it.
if (sessionValue > clsValue) {
clsValue = sessionValue;
clsEntries = sessionEntries;

// Log the updated value (and its entries) to the console.
console.log('CLS:', clsValue, clsEntries)
}
}
}
}).observe({type: 'layout-shift', buffered: true});

Advertencia:

Este código muestra la forma básica de calcular y registrar CLS. Sin embargo, medir CLS con precisión de una manera que coincida con lo que se mide en el Chrome User Experience Report (CrUX) es más complicado. Consulte a continuación para obtener más información

En la mayoría de los casos, el valor CLS actual en el momento en que se descarga la página es el valor CLS final para esa página, pero hay algunas excepciones importantes:

La siguiente sección enumera las diferencias entre lo que informa la API y cómo se calcula la métrica.

Diferencias entre la métrica y la API #

  • Si una página se carga en segundo plano, o si está en segundo plano antes de que el navegador describa cualquier contenido, entonces no debería informar ningún valor CLS.
  • Si se restaura una página desde la caché de retroceso/avance, su valor CLS debe restablecerse a cero, ya que los usuarios experimentan esto como una visita de una página distinta.
  • La API no informa a las entradas layout-shift de los cambios que ocurren dentro de los iframes, pero para medir CLS correctamente, debe considerarlos. Los sub-frames pueden utilizar la API para informar a sus layout-shift hacia el marco principal para su incorporación.

Además de estas excepciones, CLS tiene cierta complejidad adicional debido al hecho de que mide la vida útil completa de una página:

  • Los usuarios pueden mantener una pestaña abierta durante mucho tiempo, días, semanas, meses. De hecho, es posible que un usuario nunca cierre una pestaña.
  • En los sistemas operativos móviles, los navegadores normalmente no ejecutan devoluciones de llamadas de descarga en la página para las pestañas en segundo plano, lo que dificulta informar el valor "final".

Para manejar estos casos, se debe informar CLS cada vez que una página está en segundo plano, además de cada vez que se descarga (el evento visibilitychange cubre ambos escenarios). Y los sistemas de análisis que reciban estos datos deberán calcular el valor CLS final en el backend.

En vez de memorizar y lidiar con todos estos casos usted mismo, los desarrolladores pueden usar la biblioteca JavaScript de web-vitals para medir CLS, que da cuenta de todo lo mencionado anteriormente:

import {getCLS} from 'web-vitals';

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

Puede consultar el código fuente de getCLS) para obtener un ejemplo completo de cómo medir CLS en JavaScript.

En algunos casos (como los iframes de origen cruzado) no es posible medir CLS en JavaScript. Consulte la sección de limitaciones de la biblioteca de web-vitals para obtener más información.

Cómo mejorar CLS #

Para la mayoría de los sitios web, puede evitar todos los cambios de diseño inesperados si sigue algunos principios básicos:

  • Siempre incluya atributos de tamaño en sus imágenes y elementos de video, o reserve el espacio requerido con algo como casillas de relación de aspecto en CSS . Este enfoque garantiza que el navegador pueda asignar la cantidad correcta de espacio en el documento mientras se carga la imagen. Tenga en cuenta que también puede utilizar la política de funciones para los medios no desarrollados para forzar este comportamiento en los navegadores que son compatibles con políticas de funciones.
  • Nunca inserte contenido por encima del contenido actual, excepto si es una respuesta a la interacción del usuario. Esto asegura que se esperen los cambios de diseño que se produzcan.
  • Prefiere transformar animaciones a animaciones de propiedades que desencadenan cambios de diseño. Anime las transiciones de una manera que proporcione contexto y continuidad de un estado a otro.

Para obtener información detallada sobre cómo mejorar CLS, consulte Optimización de CLS y Cambios de diseño de depuración .

Recursos adicionales #

CHANGELOG #

Occasionally, bugs are discovered in the APIs used to measure metrics, and sometimes in the definitions of the metrics themselves. As a result, changes must sometimes be made, and these changes can show up as improvements or regressions in your internal reports and dashboards.

To help you manage this, all changes to either the implementation or definition of these metrics will be surfaced in this CHANGELOG.

Última actualización: Mejorar el artículo