Les grandes tailles de DOM ont plus d'impact sur l'interactivité que vous ne le pensez. Ce guide vous explique pourquoi et ce que vous pouvez faire.
Il n'y a aucun moyen de contourner ce problème: lorsque vous créez une page Web, celle-ci est associée à 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 est toutefois 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 grand, plus il est coûteux d'afficher initialement cette page et de mettre à jour son rendu plus tard dans le cycle de vie de la page.
Cela devient problématique dans les pages comportant des DOM très volumineux, lorsque les interactions qui modifient ou mettent à jour le DOM déclenchent une mise en page coûteuse qui affecte la capacité de la page à répondre rapidement. Les efforts coûteux de mise en page peuvent affecter le taux d'Interaction to Next Paint (INP) d'une page. Si vous souhaitez qu'une page réagisse rapidement aux interactions des utilisateurs, vous devez vous assurer que la taille de vos DOM n'est pas limitée.
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 commence à générer des avertissements lorsque le DOM d'une page dépasse 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>
Le code ci-dessus comporte quatre éléments DOM: l'élément <ul>
et ses trois éléments enfants <li>
. Votre page Web comportera certainement beaucoup plus de nœuds que cela. Il est donc important de comprendre ce que vous pouvez faire pour contrôler les tailles DOM, ainsi que d'autres stratégies pour optimiser le travail d'affichage une fois que le DOM d'une page est aussi petit que possible.
Comment les grands DOM affectent-ils les performances des pages ?
Les DOM volumineux affectent les performances des pages de plusieurs façons:
- Pendant l'affichage initial de la page Lorsque le code CSS est appliqué à une page, une structure semblable au DOM, appelée CSSOM (CSS Object Model), est créée. À mesure que la spécificité des sélecteurs CSS augmente, le CSSOM devient plus complexe, et plus de temps est nécessaire pour exécuter les opérations de mise en page, de style, de composition et de peinture nécessaires pour dessiner la page Web à l'écran. Ce travail supplémentaire augmente la latence des interactions qui se produisent tôt lors du chargement de la page.
- Lorsque les interactions modifient le DOM, que ce soit par l'insertion ou la suppression d'éléments, ou par la modification du contenu et des styles du DOM, le travail nécessaire à l'affichage de cette mise à jour peut s'avérer très coûteux en termes de mise en page, de style, de composition et de peinture. Comme pour l'affichage initial de la page, une augmentation de la spécificité du sélecteur CSS peut influer sur l'affichage lorsque des éléments HTML sont insérés dans le DOM à la suite d'une interaction.
- 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 de la mémoire peut être considérable si le résultat renvoie un grand nombre d'éléments DOM.
![Capture d'écran d'une longue tâche causée par des tâches d'affichage excessives dans le panneau "Performances" des outils pour les développeurs Chrome. La pile d'appel de la tâche longue indique un temps important passé à recalculer les styles de page, ainsi que le pré-peinture.](https://web.dev/static/articles/dom-size-and-interactivity/image/a-screenshot-a-long-task-a768ec4a643a9.png?authuser=6&hl=fr)
Tous ces éléments peuvent avoir une incidence sur 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, elle peut lancer de nombreuses tâches qui peuvent contribuer à un INP médiocre sur une page.
Comment mesurer la taille d'un DOM ?
Il existe plusieurs façons de mesurer la taille du DOM. La première méthode utilise Lighthouse. Lorsque vous exécutez un audit, les statistiques sur le DOM de la page actuelle se trouvent dans la catégorie "Éviter une taille de DOM excessive". dans la section "Diagnostic" en haut à droite. Dans cette section, vous pouvez voir le nombre total d'éléments DOM, l'élément DOM contenant le plus d'éléments enfants et l'élément DOM le plus profond.
Une méthode plus simple consiste à utiliser la console JavaScript dans les outils pour les développeurs dans les principaux navigateurs. 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 mise à jour de la taille du DOM 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 (et d'autres aspects des performances) avec la taille DOM actuelle.
![Capture d'écran de l'outil de contrôle des performances dans les outils pour les développeurs Chrome. À gauche, il est possible de surveiller en permanence les performances d'une page tout au long de sa durée de vie. Dans la capture d'écran, le nombre de nœuds DOM, les mises en page par seconde et les recalculs de style par section sont activement surveillés.](https://web.dev/static/articles/dom-size-and-interactivity/image/a-screenshot-the-perform-d46dd7f32a5de.png?authuser=6&hl=fr)
Si la taille du DOM approche le seuil d'avertissement de la taille du DOM Lighthouse, ou s'il échoue complètement, vous devez 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 dans l'atelier qui pourrait avoir un rapport avec la taille du DOM de la page, vous pouvez déterminer combien d'éléments DOM ont été affectés en sélectionnant n'importe quelle activité dans le profileur intitulée "Recalculate Style" (Recalculer le style). et observez les données contextuelles dans le panneau du bas.
![Capture d'écran de l'activité de recalcul des styles sélectionnée dans le panneau "Performances" des outils pour les développeurs Chrome. En haut, le suivi des interactions affiche une interaction basée sur un clic. La majeure partie du travail est consacrée au recalcul du style et au travail pré-peinture. En bas, un panneau affiche des informations plus détaillées sur l'activité sélectionnée. Elle indique que 2 547 éléments DOM ont été affectés.](https://web.dev/static/articles/dom-size-and-interactivity/image/a-screenshot-selected-st-9a6c0cc217aa3.png?authuser=6&hl=fr)
Dans la capture d'écran ci-dessus, notez que le recalcul du style du travail (lorsque celui-ci est sélectionné) 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 sur 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 frame suivant en réponse à une interaction.
Comment réduire la taille d'un DOM ?
Au-delà d'un audit du code HTML de votre site Web pour détecter tout balisage inutile, le principal moyen de réduire la taille d'un DOM consiste à réduire sa profondeur. Si vous voyez un balisage qui ressemble à ceci dans l'onglet Éléments des outils pour les développeurs 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 votre 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. Plus spécifiquement, les frameworks basés sur des composants (tels que ceux qui reposent sur JSX) nécessitent l'imbrication de plusieurs composants dans un conteneur parent.
Cependant, de nombreux frameworks vous permettent d'éviter l'imbrication de composants en utilisant ce que l'on appelle des fragments. Les frameworks basés sur des composants qui proposent des fragments en tant que fonctionnalité incluent, sans s'y limiter, les éléments suivants:
En utilisant des fragments dans le framework de votre choix, vous pouvez réduire la profondeur du DOM. Si vous êtes préoccupé par l'impact de l'aplatissement de la structure DOM sur les styles, 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 prenez le temps d'aplatir l'arborescence DOM et de supprimer les éléments HTML inutiles pour réduire au maximum la taille de votre DOM, il peut s'avérer assez volumineux et générer beaucoup de travail d'affichage, car il change en fonction des interactions des utilisateurs. Si vous vous trouvez à cet endroit, il existe d'autres stratégies que vous pouvez envisager pour limiter le travail d'affichage.
Envisager une approche additive
Il se peut que de grandes parties de votre page ne soient pas initialement visibles par l'utilisateur lors de son 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 de les ajouter 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 pendant le chargement initial et peut-être même après. Pour le chargement initial de la page, vous avez moins de travail d'affichage en amont, ce qui signifie que votre charge utile HTML initiale sera plus légère et s'affichera plus rapidement. Cela donnera aux interactions au cours de cette période cruciale plus d'occasions de fonctionner avec moins de concurrence pour l'attention du thread principal.
Si de nombreuses parties de la page sont initialement masquées lors du chargement, cela peut également accélérer d'autres interactions déclenchant un nouvel affichage. Toutefois, à mesure que d'autres interactions ajoutent des éléments au DOM, la charge de rendu augmente à mesure que le DOM se développe tout au long du cycle de vie de la page.
L'ajout au DOM au fil du temps peut s'avérer délicat et présenter ses propres compromis. Dans ce cas, vous effectuez probablement des requêtes réseau pour obtenir des données afin de renseigner le code HTML que vous souhaitez ajouter à la page en réponse à une interaction utilisateur. Bien que les requêtes réseau en cours de transfert ne soient pas comptabilisées dans l'INP, cela peut augmenter la latence perçue. Si possible, affichez une icône de chargement ou un autre indicateur indiquant que des données sont en cours de récupération afin que les utilisateurs comprennent que quelque chose se passe.
Limiter la complexité du sélecteur CSS
Lorsque le navigateur analyse des sélecteurs dans votre CSS, il doit parcourir l'arborescence DOM pour comprendre comment ces sélecteurs s'appliquent à la mise en page actuelle, et si oui, comment. Plus ces sélecteurs sont complexes, plus le navigateur doit effectuer de travail pour effectuer à la fois le rendu initial de la page et, en cas de modification de la page suite à une interaction, davantage de recalculs de style et de mise en page.
Utiliser la propriété content-visibility
CSS propose la propriété content-visibility
, qui permet d'afficher de manière différée les éléments DOM hors écran. Lorsque les éléments s'approchent de la fenêtre d'affichage, ils sont affichés à la demande. content-visibility
permet non seulement d'alléger le rendu initial de la page, mais également d'ignorer le travail d'affichage pour les éléments hors écran lorsque le DOM de la page est modifié suite à une interaction de l'utilisateur.
Conclusion
Réduire la taille de votre DOM uniquement pour le strict nécessaire est un bon moyen d'optimiser l'INP de votre site Web. Ainsi, vous pouvez réduire le temps nécessaire au navigateur pour effectuer les tâches de mise en page et d'affichage lorsque le DOM est mis à jour. Même si vous ne pouvez pas réduire de manière significative la taille du DOM, vous pouvez utiliser certaines techniques pour isoler le travail de rendu dans une sous-arborescence DOM, comme le confinement CSS et la propriété CSS content-visibility
.
Quelle que soit la façon dont vous procédez, en créant un environnement dans lequel le travail de rendu est minimisé, tout en réduisant la quantité de travail d'affichage de votre page en réponse aux interactions, votre site Web sera plus réactif aux utilisateurs lorsqu'ils interagissent avec eux. Vous obtiendrez donc un INP plus faible pour votre site Web, ce qui se traduira par une meilleure expérience utilisateur.
Image principale tirée de Unsplash, par Louis Reed.