L'impact des grandes tailles de DOM sur l'interactivité et ce que vous pouvez faire pour y remédier

La taille du DOM a un impact plus important sur l'interactivité que vous ne le pensez. Ce guide vous explique pourquoi et ce que vous pouvez faire.

Il n'y a pas d'échappatoire : lorsque vous créez une page Web, celle-ci comporte un Document Object Model (DOM). Le DOM représente la structure du code HTML de votre page et permet à JavaScript et CSS d'accéder à la structure et au contenu d'une page.

Le problème, cependant, est que la taille du DOM affecte la capacité d'un navigateur à afficher une page rapidement et efficacement. En règle générale, plus un DOM est volumineux, plus il est coûteux de rendre la page initialement et de mettre à jour son rendu plus tard dans le cycle de vie de la page.

Cela devient problématique sur les pages avec des DOM très volumineux lorsque des interactions qui modifient ou mettent à jour le DOM déclenchent un travail de mise en page coûteux qui affecte la capacité de la page à répondre rapidement. Les tâches de mise en page coûteuses peuvent affecter l'Interaction to Next Paint (INP) d'une page. Si vous souhaitez qu'une page réponde rapidement aux interactions des utilisateurs, il est important de vous assurer que la taille de votre DOM n'est pas plus grande que nécessaire.

Quand le DOM d'une page est-il trop volumineux ?

Selon Lighthouse, la taille du DOM d'une page est excessive lorsqu'elle dépasse 1 400 nœuds. Lighthouse commencera à générer des avertissements lorsque le DOM d'une page dépassera 800 nœuds. Prenons l'exemple du code HTML suivant :

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

Dans le code ci-dessus, il existe quatre éléments DOM : l'élément <ul> et ses trois éléments enfants <li>. Votre page Web comportera presque certainement beaucoup plus de nœuds. Il est donc important de comprendre ce que vous pouvez faire pour contrôler la taille du DOM, ainsi que d'autres stratégies pour optimiser le rendu une fois que le DOM d'une page est aussi petit que possible.

Quel est l'impact des DOM volumineux sur les performances des pages ?

Les DOM volumineux affectent les performances des pages de plusieurs manières :

  1. Lors du rendu initial de la page. Lorsqu'un CSS est appliqué à une page, une structure semblable au DOM, appelée CSS Object Model (CSSOM), est créée. À mesure que la spécificité des sélecteurs CSS augmente, le CSSOM devient plus complexe et il faut plus de temps pour exécuter les tâches de mise en page, de style, de composition et de peinture nécessaires pour afficher la page Web à l'écran. Ce travail supplémentaire augmente la latence des interactions qui se produisent au début du chargement de la page.
  2. Lorsque des interactions modifient le DOM, que ce soit par l'insertion ou la suppression d'éléments, ou en modifiant le contenu et les styles du DOM, le travail nécessaire pour rendre cette mise à jour peut entraîner des opérations de mise en page, de style, de composition et de peinture très coûteuses. Comme pour le rendu initial de la page, une spécificité accrue du sélecteur CSS peut ajouter du travail de rendu lorsque des éléments HTML sont insérés dans le DOM à la suite d'une interaction.
  3. Lorsque JavaScript interroge le DOM, les références aux éléments DOM sont stockées en mémoire. Par exemple, si vous appelez document.querySelectorAll pour sélectionner tous les éléments <div> d'une page, le coût en mémoire peut être considérable si le résultat renvoie un grand nombre d'éléments DOM.
Capture d&#39;écran d&#39;une tâche longue causée par un rendu excessif dans le panneau &quot;Performances&quot; des outils pour les développeurs Chrome. La pile d&#39;appels de la tâche longue montre qu&#39;une partie importante du temps est consacrée au recalcul des styles de page, ainsi qu&#39;à la prépeinture.
Tâche longue telle qu'elle apparaît dans le profileur de performances des outils pour les développeurs Chrome. La longue tâche affichée est due à l'insertion d'éléments DOM dans un grand DOM via JavaScript.

Tous ces éléments peuvent affecter l'interactivité, mais le deuxième élément de la liste ci-dessus est particulièrement important. Si une interaction entraîne une modification du DOM, cela peut déclencher de nombreuses tâches qui peuvent contribuer à une INP médiocre sur une page.

Comment mesurer la taille du DOM ?

Vous pouvez mesurer la taille du DOM de plusieurs façons. La première méthode utilise Lighthouse. Lorsque vous effectuez un audit, les statistiques sur le DOM de la page actuelle se trouvent dans l'audit "Évitez une taille excessive de DOM" sous l'en-tête "Diagnostic". Dans cette section, vous pouvez voir le nombre total d'éléments DOM, l'élément DOM contenant le plus d'éléments enfants, ainsi que l'élément DOM le plus profond.

Une méthode plus simple consiste à utiliser la console JavaScript dans les outils pour les développeurs de n'importe quel navigateur majeur. Pour obtenir le nombre total d'éléments HTML dans le DOM, vous pouvez utiliser le code suivant dans la console une fois la page chargée :

document.querySelectorAll('*').length;

Si vous souhaitez voir la taille du DOM se mettre à jour en temps réel, vous pouvez également utiliser l'outil de contrôle des performances. Cet outil vous permet de corréler les opérations de mise en page et de style (ainsi que d'autres aspects liés aux performances) avec la taille actuelle du DOM.

Capture d&#39;écran du moniteur de performances dans les outils pour les développeurs Chrome. À gauche, vous trouverez différents aspects des performances des pages qui peuvent être surveillés en continu pendant la durée de vie de la page. Dans la capture d&#39;écran, le nombre de nœuds DOM, de mises en page par seconde et de nouveaux calculs de style par section sont activement surveillés.
Le moniteur de performances dans les outils pour les développeurs Chrome. Dans cette vue, le nombre actuel de nœuds DOM de la page est représenté sous forme de graphique, ainsi que les opérations de mise en page et les nouveaux calculs de style effectués par seconde.

Si la taille du DOM approche du seuil d'avertissement de Lighthouse ou échoue complètement, l'étape suivante consiste à déterminer comment réduire la taille du DOM pour améliorer la capacité de votre page à répondre aux interactions des utilisateurs, afin d'améliorer l'INP de votre site Web.

Comment mesurer le nombre d'éléments DOM affectés par une interaction ?

Si vous profilez une interaction lente en laboratoire qui, selon vous, pourrait être liée à la taille du DOM de la page, vous pouvez déterminer le nombre d'éléments DOM concernés en sélectionnant n'importe quelle activité du profileur intitulée "Recalculer le style" et en observant les données contextuelles dans le panneau inférieur.

Capture d&#39;écran de l&#39;activité de recalcul de style sélectionnée dans le panneau &quot;Performances&quot; de Chrome DevTools. En haut, la piste des interactions montre une interaction de clic, et la majorité du travail est consacrée au recalcul du style et au travail de pré-peinture. En bas de l&#39;écran, un panneau affiche plus de détails sur l&#39;activité sélectionnée, qui indique que 2 547 éléments DOM ont été affectés.
Observation du nombre d'éléments affectés dans le DOM à la suite du recalcul du style. Notez que la partie ombrée de l'interaction dans la piste des interactions représente la partie de la durée de l'interaction qui a dépassé 200 millisecondes, ce qui correspond au seuil "bon" désigné pour l'INP.

Dans la capture d'écran ci-dessus, notez que le recalcul du style de l'œuvre (lorsqu'elle est sélectionnée) indique le nombre d'éléments concernés. Bien que la capture d'écran ci-dessus montre un cas extrême de l'effet de la taille du DOM sur le rendu d'une page comportant de nombreux éléments DOM, ces informations de diagnostic sont utiles dans tous les cas pour déterminer si la taille du DOM est un facteur limitant le temps nécessaire à l'affichage du prochain frame en réponse à une interaction.

Comment réduire la taille du DOM ?

Au-delà de l'audit du code HTML de votre site Web pour identifier les balises inutiles, le principal moyen de réduire la taille du DOM consiste à réduire sa profondeur. Si vous voyez un balisage qui ressemble à ceci dans l'onglet Éléments des outils de développement de votre navigateur, cela peut indiquer que votre DOM est inutilement profond :

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

Lorsque vous voyez des modèles comme celui-ci, vous pouvez probablement les simplifier en aplatissant la structure DOM. Cela réduira le nombre d'éléments DOM et vous permettra probablement de simplifier les styles de page.

La profondeur du DOM peut également être un symptôme des frameworks que vous utilisez. En particulier, les frameworks basés sur des composants, tels que ceux qui s'appuient sur JSX, vous obligent à imbriquer plusieurs composants dans un conteneur parent.

Toutefois, de nombreux frameworks vous permettent d'éviter d'imbriquer des composants en utilisant ce que l'on appelle des fragments. Voici quelques exemples de frameworks basés sur des composants qui proposent des fragments :

En utilisant des fragments dans le framework de votre choix, vous pouvez réduire la profondeur du DOM. Si vous craignez que l'aplatissement de la structure DOM ait un impact sur le style, vous pouvez utiliser des modes de mise en page plus modernes (et plus rapides) tels que flexbox ou grid.

Autres stratégies à envisager

Même si vous vous efforcez d'aplatir votre arborescence DOM et de supprimer les éléments HTML inutiles pour que votre DOM soit aussi petit que possible, il peut quand même être assez volumineux et déclencher de nombreux travaux de rendu lorsqu'il change en réponse aux interactions des utilisateurs. Si vous vous trouvez dans cette situation, vous pouvez envisager d'autres stratégies pour limiter le travail de rendu.

Envisagez une approche additive

Il est possible que de grandes parties de votre page ne soient pas visibles par l'utilisateur lors du premier rendu. Cela peut être l'occasion de charger le code HTML de manière différée en omettant ces parties du DOM au démarrage, mais en les ajoutant lorsque l'utilisateur interagit avec les parties de la page qui nécessitent les aspects initialement masqués de la page.

Cette approche est utile à la fois lors du chargement initial et peut-être même après. Pour le chargement initial de la page, vous effectuez moins de rendu au départ, ce qui signifie que votre charge utile HTML initiale sera plus légère et s'affichera plus rapidement. Les interactions pendant cette période cruciale auront ainsi plus de chances de s'exécuter, car la concurrence pour l'attention du thread principal sera moins forte.

Si de nombreuses parties de la page sont initialement masquées au chargement, cela peut également accélérer d'autres interactions qui déclenchent un travail de rendu. Toutefois, à mesure que d'autres interactions ajoutent des éléments au DOM, le travail de rendu augmente à mesure que le DOM se développe tout au long du cycle de vie de la page.

Ajouter des éléments au DOM au fil du temps peut être délicat et présente ses propres inconvénients. Si vous choisissez cette approche, vous effectuez probablement des requêtes réseau pour obtenir les données permettant de remplir le code HTML que vous souhaitez ajouter à la page en réponse à une interaction utilisateur. Bien que les requêtes réseau en cours ne soient pas comptabilisées dans l'INP, elles peuvent augmenter la latence perçue. Si possible, affichez un indicateur de chargement ou un autre indicateur pour indiquer aux utilisateurs que des données sont en cours de récupération.

Limiter la complexité des sélecteurs CSS

Lorsque le navigateur analyse les sélecteurs dans votre CSS, il doit parcourir l'arborescence DOM pour comprendre comment et si ces sélecteurs s'appliquent à la mise en page actuelle. Plus ces sélecteurs sont complexes, plus le navigateur doit travailler pour effectuer le rendu initial de la page, ainsi que pour recalculer les styles et la mise en page si la page change à la suite d'une interaction.

Utiliser la propriété content-visibility

Le CSS propose la propriété content-visibility, qui permet d'effectuer un rendu différé des éléments DOM hors écran. À mesure que les éléments approchent de la fenêtre d'affichage, ils sont affichés à la demande. Les avantages de content-visibility ne se limitent pas à réduire considérablement le travail de rendu lors du rendu initial de la page. Ils permettent également d'éviter le rendu des éléments hors écran lorsque le DOM de la page est modifié à la suite d'une interaction de l'utilisateur.

Conclusion

Réduire la taille du DOM à ce qui est strictement nécessaire est un bon moyen d'optimiser l'INP de votre site Web. Vous pouvez ainsi réduire le temps nécessaire au navigateur pour effectuer la mise en page et le rendu lorsque le DOM est mis à jour. Même si vous ne pouvez pas réduire de manière significative la taille du DOM, il existe des techniques que vous pouvez utiliser pour isoler le travail de rendu dans un sous-arbre DOM, comme le confinement CSS et la propriété CSS content-visibility.

Quelle que soit la méthode que vous choisissez, si vous créez un environnement où le travail de rendu est minimisé et que vous réduisez la quantité de travail de rendu que votre page effectue en réponse aux interactions, votre site Web semblera plus réactif pour les utilisateurs lorsqu'ils interagiront avec lui. Cela signifie que l'INP de votre site Web sera plus faible, ce qui se traduit par une meilleure expérience utilisateur.