Cómo depurar cambios de diseño

Obtén información para identificar y corregir los cambios de diseño.

Katie Hempenius
Katie Hempenius

En la primera parte de este artículo, se analizan las herramientas para depurar cambios de diseño, mientras que en la segunda, se analiza el proceso de pensamiento que se debe usar para identificar la causa de un cambio de diseño.

Herramientas

API de Layout Instability

La API de inestabilidad de diseño es el mecanismo del navegador para medir e informar cambios de diseño. Todas las herramientas para depurar cambios de diseño, incluidas las Herramientas para desarrolladores, se compilan en última instancia sobre la API de inestabilidad de diseño. Sin embargo, el uso directo de la API de inestabilidad de diseño es una herramienta de depuración muy potente debido a su flexibilidad.

Uso

El mismo fragmento de código que mide el Cambio de diseño acumulado (CLS) también puede servir para depurar cambios de diseño. El siguiente fragmento registra información sobre los cambios de diseño en la consola. La inspección de este registro te proporcionará información sobre cuándo, dónde y cómo se produjo un cambio de diseño.

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Cuando ejecutes esta secuencia de comandos, ten en cuenta lo siguiente:

  • La opción buffered: true indica que PerformanceObserver debe verificar el búfer de entrada de rendimiento del navegador para ver las entradas de rendimiento que se crearon antes de la inicialización del observador. Como resultado, PerformanceObserver informará los cambios de diseño que ocurrieron antes y después de que se inicializó. Ten esto en cuenta cuando inspecciones los registros de la consola. Un exceso inicial de cambios de diseño puede reflejar una lista de informes, en lugar de un caso repentino de varios cambios de diseño.
  • Para evitar afectar el rendimiento, PerformanceObserver espera hasta que el subproceso principal esté inactivo para informar sobre los cambios de diseño. Como resultado, según cuán ocupado esté el subproceso principal, puede haber una leve demora entre el momento en que se produce un cambio de diseño y el momento en el que se registra en la consola.
  • Esta secuencia de comandos ignora los cambios de diseño que se produjeron dentro de los 500 ms de la entrada del usuario y, por lo tanto, no se tienen en cuenta para el CLS.

La información sobre los cambios de diseño se informa usando una combinación de dos APIs: las interfaces LayoutShift y LayoutShiftAttribution. Cada una de estas interfaces se explica con más detalle en las siguientes secciones.

LayoutShift

Cada cambio de diseño se informa con la interfaz LayoutShift. El contenido de una entrada se ve de la siguiente manera:

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

La entrada anterior indica un cambio de diseño durante el cual se modificó la posición de tres elementos del DOM. La puntuación de cambio de diseño correspondiente a este cambio de diseño en particular fue 0.175.

Estas son las propiedades de una instancia de LayoutShift que son más relevantes para depurar cambios de diseño:

Propiedad Descripción
sources La propiedad sources enumera los elementos del DOM que se movieron durante el cambio de diseño. Este array puede contener hasta cinco fuentes. En el caso de que haya más de cinco elementos afectados por el cambio de diseño, se informarán las cinco fuentes de cambio de diseño más grandes (según las mediciones del impacto en la estabilidad del diseño). Esta información se informa mediante la interfaz LayoutShiftAttribution (se explica con más detalle a continuación).
value La propiedad value informa la puntuación de cambio de diseño para un cambio de diseño particular.
hadRecentInput La propiedad hadRecentInput indica si se produjo un cambio de diseño dentro de los 500 milisegundos posteriores a la entrada del usuario.
startTime La propiedad startTime indica cuándo se produjo un cambio de diseño. startTime se indica en milisegundos y se mide en relación con el momento en el que se inició la carga de la página.
duration La propiedad duration siempre se establecerá como 0. Esta propiedad se hereda de la interfaz PerformanceEntry (la interfaz LayoutShift extiende la interfaz PerformanceEntry). Sin embargo, el concepto de duración no se aplica a los eventos de cambio de diseño, por lo que se establece en 0. Para obtener información sobre la interfaz PerformanceEntry, consulta la spec.

LayoutShiftAttribution

La interfaz LayoutShiftAttribution describe un solo cambio en un solo elemento del DOM. Si varios elementos cambian durante un cambio de diseño, la propiedad sources contiene varias entradas.

Por ejemplo, el siguiente JSON corresponde a un cambio de diseño con una fuente: el cambio hacia abajo del elemento <div id='banner'> del DOM de y: 76 a y:246.

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

La propiedad node identifica el elemento HTML que cambió. Cuando colocas el cursor sobre esta propiedad en Herramientas para desarrolladores, se destaca el elemento de página correspondiente.

Las propiedades previousRect y currentRect informan el tamaño y la posición del nodo.

  • Las coordenadas x y y informan las coordenadas X y Y, respectivamente, de la esquina superior izquierda del elemento
  • Las propiedades width y height informan el ancho y la altura del elemento respectivamente.
  • Las propiedades top, right, bottom y left informan los valores de coordenadas x o y correspondientes al borde determinado del elemento. En otras palabras, el valor de top es igual a y; el valor de bottom es igual a y+height.

Si todas las propiedades de previousRect se establecen en 0, significa que el elemento pasó a ser visible. Si todas las propiedades de currentRect se establecen en 0, significa que el elemento se movió fuera de la vista.

Uno de los aspectos más importantes que debes comprender cuando interpretas estos resultados es que los elementos enumerados como fuentes son aquellos que se modifican durante el cambio de diseño. Sin embargo, es posible que estos elementos solo se relacionen indirectamente con la "causa raíz" de la inestabilidad del diseño. Estos son algunos ejemplos.

Ejemplo 1

Este cambio de diseño se informaría con una fuente: el elemento B. Sin embargo, la causa raíz de este cambio de diseño es el cambio de tamaño del elemento A.

Ejemplo en el que se muestra un cambio de diseño causado por un cambio en las dimensiones de los elementos

Ejemplo 2

El cambio de diseño en este ejemplo se informaría con dos fuentes: el elemento A y el elemento B. La causa raíz de este cambio de diseño es el cambio de posición del elemento A.

Ejemplo en el que se muestra un cambio de diseño causado por un cambio en la posición de un elemento

Ejemplo 3

El cambio de diseño en este ejemplo se informaría con una fuente: el elemento B. El cambio de posición del elemento B provocó este cambio de diseño.

Ejemplo en el que se muestra un cambio de diseño causado por un cambio en la posición de un elemento

Ejemplo 4

Aunque el elemento B cambia de tamaño, no hay un cambio de diseño en este ejemplo.

Ejemplo en el que se muestra un elemento que cambia de tamaño, pero no causa un cambio de diseño

Consulta una demostración de cómo la API de inestabilidad de diseño informa los cambios del DOM.

DevTools

Panel de rendimiento

El panel Experiencia en el panel Performance de Herramientas para desarrolladores muestra todos los cambios de diseño que ocurren durante un seguimiento de rendimiento determinado, incluso si ocurren dentro de los 500 ms de una interacción del usuario y, por lo tanto, no se registran para CLS. Cuando colocas el cursor sobre un cambio de diseño específico en el panel Experiencia (Experience), se destaca el elemento del DOM afectado.

Captura de pantalla de un cambio de diseño que se muestra en el panel Network de Herramientas para desarrolladores

Para ver más información sobre el cambio de diseño, haz clic en el cambio de diseño y, luego, abre el panel lateral Resumen. Los cambios en las dimensiones del elemento se enumeran con el formato [width, height]; los cambios en la posición del elemento se enumeran con el formato [x,y]. La propiedad Had recent input indica si se produjo un cambio de diseño dentro de los 500 ms de una interacción del usuario.

Captura de pantalla de la pestaña &quot;Summary&quot; de Herramientas para desarrolladores para un cambio de diseño

Para obtener información sobre la duración de un cambio de diseño, abre la pestaña Registro de eventos. La duración de un cambio de diseño también se puede aproximar. Para ello, consulta la longitud del rectángulo rojo de cambio de diseño en el panel Experiencia.

Captura de pantalla de la pestaña &quot;Event Log&quot; de Herramientas para desarrolladores para un cambio de diseño

Para obtener más información sobre el uso del panel Rendimiento, consulta Referencia de análisis de rendimiento.

Cómo destacar las regiones de cambio de diseño

Resaltar las regiones de cambio de diseño puede ser una técnica útil para obtener una visión rápida y resumida de la ubicación y el momento de los cambios de diseño que se producen en una página.

Para habilitar las regiones de cambio de diseño en Herramientas para desarrolladores, ve a Configuración > Más herramientas > Renderización > Regiones de cambio de diseño y, luego, actualiza la página que deseas depurar. Las áreas de cambio de diseño se destacarán brevemente en púrpura.

Proceso de pensamiento para identificar la causa de los cambios de diseño

Puedes usar los pasos que se indican a continuación para identificar la causa de los cambios de diseño sin importar cuándo o cómo se produzcan. Estos pasos se pueden complementar con la ejecución de Lighthouse. Sin embargo, ten en cuenta que Lighthouse solo puede identificar los cambios de diseño que se produjeron durante la carga inicial de la página. Además, Lighthouse solo puede proporcionar sugerencias para algunas causas de cambios de diseño, por ejemplo, elementos de imagen que no tienen ancho y altura explícitos.

Cómo identificar la causa de un cambio de diseño

Los cambios de diseño pueden deberse a los siguientes eventos:

  • Cambios en la posición de un elemento del DOM
  • Cambios en las dimensiones de un elemento del DOM
  • Inserción o eliminación de un elemento del DOM
  • Animaciones que activan el diseño

En particular, el elemento del DOM que antecede al elemento desplazado es el que tiene más probabilidades de estar involucrado en la "causa" del cambio de diseño. Por lo tanto, cuando investigues por qué ocurrió un cambio de diseño, ten en cuenta lo siguiente:

  • ¿Cambiaron la posición o las dimensiones del elemento anterior?
  • ¿Se insertó o quitó un elemento del DOM antes del elemento desplazado?
  • ¿Se cambió explícitamente la posición del elemento desplazado?

Si el elemento anterior no causó el cambio de diseño, continúa con la búsqueda y considera otros elementos anteriores y cercanos.

Además, la dirección y la distancia de un cambio de diseño pueden proporcionar sugerencias sobre la causa raíz. Por ejemplo, un gran cambio hacia abajo suele indicar la inserción de un elemento del DOM, mientras que un cambio de diseño de 1 px o 2 px suele indicar la aplicación de estilos de CSS en conflicto o la carga y aplicación de una fuente web.

Diagrama que muestra un cambio de diseño causado por un intercambio de fuentes
En este ejemplo, el intercambio de fuentes hizo que los elementos de página se desplazaran hacia arriba cinco píxeles.

Estos son algunos de los comportamientos específicos que causan con mayor frecuencia eventos de cambio de diseño:

Cambios en la posición de un elemento (que no se deben al movimiento de otro elemento)

A menudo, este tipo de cambio es el resultado de lo siguiente:

  • Hojas de estilo que se cargan tarde o reemplazan los estilos declarados con anterioridad.
  • Efectos de animación y transición

Cambios en las dimensiones de un elemento

A menudo, este tipo de cambio es el resultado de lo siguiente:

  • Hojas de estilo que se cargan tarde o reemplazan los estilos declarados con anterioridad.
  • iframes y imágenes sin atributos width y height que se cargan después de que se renderiza su "ranura"
  • Bloques de texto sin atributos width o height que intercambian fuentes después de que se renderiza el texto

Inserción o eliminación de elementos del DOM

Suele ser el resultado de lo siguiente:

  • Inserción de anuncios y otras incorporaciones de terceros
  • Inserción de banners, alertas y modales
  • Desplazamiento infinito y otros patrones de UX que cargan contenido adicional encima del contenido existente

Animaciones que activan el diseño

Algunos efectos de animación pueden activar el diseño. Un ejemplo común de esto ocurre cuando los elementos del DOM se "animan" con el aumento de propiedades como top o left, en lugar de usar la propiedad transform de CSS. Consulta Cómo crear animaciones de CSS de alto rendimiento para obtener más información.

Cómo reproducir cambios de diseño

No puedes corregir los cambios de diseño que no puedes reproducir. Una de las medidas más simples y eficaces que puedes tomar para comprender mejor la estabilidad del diseño de tu sitio es tomarte entre 5 y 10 minutos para interactuar con él con el objetivo de activar los cambios de diseño. Mantén la consola abierta mientras haces esto y usa la API de inestabilidad de diseño para informar sobre los cambios de diseño.

Para cambios de diseño difíciles de ubicar, te recomendamos repetir este ejercicio con diferentes dispositivos y velocidades de conexión. En particular, usar una velocidad de conexión más lenta puede facilitar la identificación de los cambios de diseño. Además, puedes usar una declaración debugger para facilitar el recorrido de los cambios de diseño.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

Por último, en el caso de los problemas de diseño que no se pueden reproducir durante el desarrollo, considera usar la API de inestabilidad de diseño junto con la herramienta de registro de frontend que elijas para recopilar más información sobre estos problemas. Consulta el código de ejemplo para hacer un seguimiento del elemento desplazado más grande en una página.