Los tamaños de DOM grandes tienen un mayor 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 la página y permite que JavaScript y CSS accedan a la estructura y el contenido de la 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 sea un DOM, más costoso será representar inicialmente esa página y actualizar su representació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 trabajos de diseño costosos que afectan la capacidad de la página para responder rápidamente. Los trabajos de diseño costosos pueden afectar la Interacción con la siguiente pintura (INP) de una página. Si quieres 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 solo sean lo suficientemente 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. Tomemos el siguiente código HTML por ejemplo:
<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 varias maneras:
- 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 Modelo de objetos de CSS (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.
- Cuando las interacciones modifican el DOM, ya sea a través de la inserción o la eliminación de elementos, o de la modificación del contenido y los estilos del DOM, el trabajo necesario para representar esa actualización puede generar costos muy costosos de diseño, estilo, composición y pintura. Como es 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.
- 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.
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 iniciarse una gran cantidad de trabajo que puede contribuir a un INP deficiente en una página.
¿Cómo mido el tamaño del DOM?
Puedes medir el tamaño del DOM de dos maneras. El primer método usa Lighthouse. Cuando ejecutes una auditoría, las estadísticas sobre el DOM de la página actual aparecerán en la sección "Evitar un tamaño excesivo del DOM" en la sección “Diagnóstico” . En esta sección, puedes ver la cantidad total de elementos del DOM, el elemento del DOM que contiene la mayor cantidad de elementos secundarios, y también el elemento del 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 una vez que se haya cargado la página:
document.querySelectorAll('*').length;
Si quieres ver la actualización de tamaño del DOM en tiempo real, también puedes usar la herramienta de supervisión de rendimiento. Con esta herramienta, puedes correlacionar las operaciones de diseño y estilo (y otros aspectos de rendimiento) junto con el tamaño actual del DOM.
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 para que el INP de tu sitio web pueda mejorar.
¿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 crees que podría tener alguna relación con el tamaño del DOM de la página, puedes determinar cuántos elementos del DOM se vieron afectados. Para ello, selecciona un fragmento de actividad en el generador de perfiles con la etiqueta "Recalculate Style". y observa los datos contextuales en el panel inferior.
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. Aunque 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 le toma pintar el siguiente fotograma 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 que si observas un lenguaje de marcado similar al siguiente en la pestaña Elements 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 uses. 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 funciones 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 para tener en cuenta
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 posició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 tal vez 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 al principio algunas partes de la página estaban ocultas durante la carga, es posible que también se aceleran otras interacciones que pueden iniciar procesos de repetición de la representació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 de tu CSS, debe desviar el árbol del DOM para comprender cómo se aplican esos selectores al diseño actual (y si lo hace). 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 efectiva de renderizar de forma diferida los 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 reducen 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 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.
Independientemente de cómo lo hagas, creando un entorno en el que se minimice el trabajo de renderización, así como también reduzcas la cantidad de trabajo de renderización que realiza tu página en respuesta a las interacciones, tu sitio web tendrá una mejor capacidad de respuesta cuando los usuarios interactúen con ellos. Esto significa que tendrás un INP más bajo para tu sitio web y eso se traduce en una mejor experiencia del usuario.
Hero image de Unsplash, de Louis Reed.