De qué manera los tamaños grandes de DOM afectan la interactividad y qué puedes hacer al respecto

Los tamaños grandes de DOM tienen más efecto en la interactividad de lo que crees. En esta guía, se explica por qué y qué puedes hacer.

No hay forma de evitarlo: cuando creas una página web, esa página tendrá un Modelo de objetos del documento (DOM). El DOM representa la estructura del código HTML de tu página y les brinda a JavaScript y CSS acceso a la estructura y el contenido de una página.

No obstante, el problema es que el tamaño del DOM afecta la capacidad de un navegador para representar una página de manera rápida y eficiente. En términos generales, cuanto más grande es un DOM, más costoso es renderizar esa página inicialmente y actualizar su renderización más adelante en el ciclo de vida de la página.

Esto se vuelve problemático en las páginas con DOM muy grandes cuando las interacciones que modifican o actualizan el DOM activan un trabajo de diseño costoso que afecta la capacidad de la página para responder con rapidez. Los trabajos de diseño costosos pueden afectar la Interacción a la siguiente pintura (INP) de una página. Si deseas que una página responda rápidamente a las interacciones del usuario, es importante que te asegures de que los tamaños de tu DOM sean solo tan grandes como sea necesario.

¿Cuándo es demasiado grande el DOM de una página?

Según Lighthouse, el tamaño del DOM de una página es excesivo cuando supera los 1,400 nodos. Lighthouse comenzará a mostrar advertencias cuando el DOM de una página supere los 800 nodos. Por ejemplo, considera el siguiente código HTML:

<ul>
  <li>List item one.</li>
  <li>List item two.</li>
  <li>List item three.</li>
</ul>

En el código anterior, hay cuatro elementos del DOM: el elemento <ul> y sus tres elementos secundarios <li>. Es casi seguro que tu página web tenga muchos más nodos que este, por lo que es importante comprender qué puedes hacer para controlar los tamaños del DOM, así como otras estrategias para optimizar el trabajo de representación una vez que el DOM de la página sea tan pequeño como sea posible.

¿Cómo afectan los DOM de gran tamaño al rendimiento de la página?

Los DOM grandes afectan el rendimiento de la página de las siguientes maneras:

  1. Durante la renderización inicial de la página Cuando se aplica CSS a una página, se crea una estructura similar al DOM conocida como CSS Object Model (CSSOM). A medida que los selectores CSS aumentan en especificidad, el CSSOM se vuelve más complejo y se necesita más tiempo para ejecutar el trabajo de diseño, estilo, composición y pintura necesario para dibujar la página web en la pantalla. Este trabajo adicional aumenta la latencia de interacción para las interacciones que ocurren al comienzo durante la carga de la página.
  2. Cuando las interacciones modifican el DOM, ya sea a través de la inserción o eliminación de elementos, o bien mediante la modificación del contenido y los estilos del DOM, el trabajo necesario para renderizar esa actualización puede generar un trabajo de diseño, aplicación de estilos, composición y pintura muy costoso. Al igual que en el caso de la renderización inicial de la página, un aumento en la especificidad del selector CSS puede aumentar el trabajo de renderización cuando se insertan elementos HTML en el DOM como resultado de una interacción.
  3. Cuando JavaScript consulta el DOM, las referencias a los elementos del DOM se almacenan en la memoria. Por ejemplo, si llamas a document.querySelectorAll para seleccionar todos los elementos <div> de una página, el costo de memoria podría ser considerable si el resultado muestra una gran cantidad de elementos del DOM.
Captura de pantalla de una tarea larga causada por un trabajo de renderización excesivo en el panel de rendimiento de las Herramientas para desarrolladores de Chrome. En la pila de llamadas de la tarea larga, se muestra un tiempo significativo para recalcular los estilos de página, además del procesamiento previo de imágenes.
Es una tarea larga, como se muestra en el generador de perfiles de rendimiento de las Herramientas para desarrolladores de Chrome. La tarea larga que se muestra se produce cuando se insertan elementos del DOM en un DOM de gran tamaño mediante JavaScript.

Todos estos pueden afectar la interactividad, pero el segundo elemento de la lista anterior es de especial importancia. Si una interacción genera un cambio en el DOM, puede iniciar mucho trabajo que puede contribuir a una INP deficiente en una página.

¿Cómo puedo medir el tamaño del DOM?

Puedes medir el tamaño del DOM de varias maneras. El primer método usa Lighthouse. Cuando ejecutes una auditoría, las estadísticas sobre el DOM de la página actual se encontrarán en la auditoría "Evita un tamaño excesivo de DOM", en el encabezado "Diagnóstico". En esta sección, puedes ver la cantidad total de elementos DOM, el elemento DOM que contiene la mayor cantidad de elementos secundarios y el elemento DOM más profundo.

Un método más simple implica usar la consola de JavaScript en las herramientas para desarrolladores en cualquier navegador principal. Para obtener la cantidad total de elementos HTML en el DOM, puedes usar el siguiente código en la consola después de que se cargue la página:

document.querySelectorAll('*').length;

Si deseas ver la actualización del tamaño del DOM en tiempo real, también puedes usar la herramienta de supervisión del rendimiento. Con esta herramienta, puedes correlacionar las operaciones de diseño y diseño de componentes (y otros aspectos de rendimiento) junto con el tamaño actual del DOM.

Captura de pantalla del monitor de rendimiento en las Herramientas para desarrolladores de Chrome. A la izquierda, se muestran varios aspectos del rendimiento de la página que se pueden supervisar de forma continua durante su ciclo de vida. En la captura de pantalla, se supervisa de forma activa la cantidad de nodos DOM, los diseños por segundo y los cálculos nuevos de estilo por sección.
El monitor de rendimiento en las Herramientas para desarrolladores de Chrome. En esta vista, se representa el número actual de nodos del DOM de la página, junto con las operaciones de diseño y las repeticiones de cálculos de estilo que se realizan por segundo.

Si el tamaño del DOM se acerca al umbral de advertencia del tamaño del DOM de Lighthouse (o falla por completo), el siguiente paso es descubrir cómo reducir el tamaño del DOM para mejorar la capacidad de tu página de responder a las interacciones del usuario, de modo que pueda mejorar el INP de tu sitio web.

¿Cómo puedo medir la cantidad de elementos del DOM afectados por una interacción?

Si estás generando perfiles de una interacción lenta en el lab que sospechas que puede tener algo que ver con el tamaño del DOM de la página, puedes averiguar cuántos elementos del DOM se vieron afectados seleccionando cualquier actividad en el generador de perfiles etiquetada como &quot;Recalculate Style&quot; y observando los datos contextuales en el panel inferior.

Captura de pantalla de la actividad de recálculo de diseño seleccionada en el panel de rendimiento de Chrome DevTools. En la parte superior, el segmento de interacciones muestra una interacción de clic, y la mayor parte del trabajo se dedica a volver a calcular el estilo y a realizar el trabajo previo a la pintura. En la parte inferior, un panel muestra más detalles de la actividad seleccionada, que informa que se vieron afectados 2,547 elementos del DOM.
Se observa la cantidad de elementos afectados en el DOM como resultado del trabajo de recálculo del diseño. Ten en cuenta que la parte sombreada de la interacción en el seguimiento de interacciones representa la parte de la duración de la interacción que fue superior a 200 milisegundos, que es el umbral designado para el INP.

En la captura de pantalla anterior, observa que el recálculo de estilo de la obra (cuando se selecciona) muestra la cantidad de elementos afectados. Si bien la captura de pantalla anterior muestra un caso extremo del efecto del tamaño del DOM en el trabajo de renderización en una página con muchos elementos del DOM, esta información de diagnóstico es útil en cualquier caso para determinar si el tamaño del DOM es un factor limitante en el tiempo que tarda el siguiente fotograma en pintarse en respuesta a una interacción.

¿Cómo puedo reducir el tamaño del DOM?

Además de auditar el HTML de tu sitio web en busca de lenguaje de marcado innecesario, el principal modo de reducir el tamaño del DOM es disminuir la profundidad del DOM. Un indicador de que tu DOM podría ser innecesariamente profundo es si ves un marcado que se ve de la siguiente manera en la pestaña Elementos de las herramientas para desarrolladores de tu navegador:

<div>
  <div>
    <div>
      <div>
        <!-- Contents -->
      </div>
    </div>
  </div>
</div>

Cuando veas patrones como este, probablemente puedas simplificarlos aplanando tu estructura de DOM. Esto reducirá la cantidad de elementos del DOM y probablemente te brinde la oportunidad de simplificar los estilos de página.

La profundidad del DOM también puede ser un síntoma de los frameworks que usas. En particular, los frameworks basados en componentes, como los que se basan en JSX, requieren que anides varios componentes en un contenedor superior.

Sin embargo, muchos frameworks te permiten evitar anidar componentes usando lo que se conoce como fragmentos. Los frameworks basados en componentes que ofrecen fragmentos como función incluyen, entre otros, los siguientes:

Si usas fragmentos en el framework que elijas, puedes reducir la profundidad del DOM. Si te preocupa el impacto que tiene en el estilo la compactación de la estructura del DOM, puedes aprovechar los modos de diseño más modernos (y rápidos), como flexbox o grid.

Otras estrategias que debes considerar

Incluso si te esfuerzas para aplanar tu árbol del DOM y quitar elementos HTML innecesarios para que tu DOM sea lo más pequeño posible, este puede ser bastante grande y, de todos modos, iniciar una gran cantidad de trabajo de renderización a medida que cambia en respuesta a las interacciones del usuario. Si te encuentras en esta situación, existen otras estrategias que puedes considerar para limitar el trabajo de renderización.

Considera un enfoque aditivo

Es posible que te encuentres en una posición en la que grandes partes de la página no sean visibles para el usuario cuando se renderiza por primera vez. Esta podría ser una oportunidad para cargar HTML de forma diferida omitiendo esas partes del DOM al inicio, pero puedes agregarlas cuando el usuario interactúe con las partes de la página que requieren los aspectos inicialmente ocultos de la página.

Este enfoque es útil durante la carga inicial y, quizás, incluso después. Para la carga inicial de la página, realizas menos trabajo de renderización por adelantado, lo que significa que tu carga útil de HTML inicial será más ligera y se renderizará más rápido. Esto permitirá que las interacciones durante ese período crucial tengan más oportunidades de ejecutarse con menos competencia para la atención del subproceso principal.

Si tienes muchas partes de la página que están ocultas inicialmente durante la carga, también podría acelerar otras interacciones que activan el trabajo de renderización. Sin embargo, a medida que otras interacciones agregan más al DOM, el trabajo de representación aumentará a medida que el DOM crezca a lo largo del ciclo de vida de la página.

Agregar elementos al DOM con el tiempo puede ser complicado y tiene sus propias desventajas. Si eliges esta opción, es probable que realices solicitudes de red para obtener datos que propaguen el código HTML que deseas agregar a la página en respuesta a una interacción del usuario. Si bien las solicitudes de red en tránsito no se cuentan para INP, puede aumentar la latencia percibida. Si es posible, muestra un ícono giratorio de carga o algún otro indicador de que los datos se están recuperando para que los usuarios comprendan que algo está sucediendo.

Limitar la complejidad del selector CSS

Cuando el navegador analiza los selectores en tu CSS, debe recorrer el árbol del DOM para comprender cómo (y si) se aplican esos selectores al diseño actual. Cuanto más complejos sean estos selectores, más trabajo deberá hacer el navegador para realizar tanto el procesamiento inicial de la página como el aumento de las recálculos de estilo y el trabajo de diseño si la página cambia como resultado de una interacción.

Usa la propiedad content-visibility

CSS ofrece la propiedad content-visibility, que es una forma eficaz de renderizar de forma diferida elementos del DOM fuera de la pantalla. A medida que los elementos se acercan al viewport, se renderizan a pedido. Los beneficios de content-visibility no solo eliminan una cantidad significativa de trabajo de renderización en la renderización inicial de la página, sino que también omiten el trabajo de renderización de los elementos fuera de la pantalla cuando se cambia el DOM de la página como resultado de una interacción del usuario.

Conclusión

Reducir el tamaño del DOM a solo lo que es estrictamente necesario es una buena forma de optimizar el INP de tu sitio web. De esta manera, puedes reducir la cantidad de tiempo que tarda el navegador en realizar trabajos de diseño y representación cuando se actualiza el DOM. Incluso si no puedes reducir significativamente el tamaño del DOM, existen algunas técnicas que puedes usar para aislar el trabajo de renderización en un subárbol del DOM, como la contención de CSS y la propiedad content-visibility de CSS.

Sin embargo, crear un entorno en el que se minimice el trabajo de renderización, además de reducir la cantidad de trabajo de renderización que realiza tu página en respuesta a las interacciones, hará que tu sitio web se sienta más responsivo para los usuarios cuando interactúen con él. Eso significa que tendrás un INP más bajo para tu sitio web y eso se traduce en una mejor experiencia del usuario.