Les DOM de grande taille ont 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'autre solution: lorsque vous créez une page Web, elle 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 de la page.
Le problème 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 l'afficher initialement et de mettre à jour son affichage plus tard dans le cycle de vie de la page.
Cela devient problématique sur les pages avec des DOM très volumineux lorsque les 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. Un travail de mise en page coûteux peut affecter l'interaction à la prochaine peinture (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 que celle 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 commence à générer des avertissements lorsque le DOM d'une page dépasse 800 nœuds. Prenons l'exemple de 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 contiendra 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 vous avez réduit le DOM d'une page au maximum.
En quoi les DOM volumineux affectent-ils les performances des pages ?
Les DOM volumineux ont plusieurs conséquences sur les performances des pages:
- Lors du rendu initial de la page. Lorsqu'un style CSS est appliqué à une page, une structure semblable au DOM appelée modèle d'objets CSS (CSSOM) est créée. À mesure que les sélecteurs CSS gagnent en spécificité, le CSSOM devient plus complexe, et il faut plus de temps pour exécuter les opérations de mise en page, de stylisation, 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 au début du chargement de la page.
- Lorsque les interactions modifient le DOM, soit par insertion ou suppression d'éléments, soit en modifiant les contenus et les styles du DOM, le travail nécessaire pour afficher cette mise à jour peut entraîner des tâches de mise en page, de stylisation, de composition et de peinture très coûteuses. Comme pour le rendu initial de la page, une augmentation de la spécificité du sélecteur CSS peut augmenter la charge de rendu 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 mémoire peut être considérable si le résultat renvoie un grand nombre d'éléments DOM.
Tous ces éléments peuvent affecter l'interactivité, mais le deuxième de la liste ci-dessus est particulièrement important. Si une interaction entraîne une modification du DOM, elle peut déclencher de nombreuses tâches qui peuvent contribuer à une mauvaise INP sur une page.
Comment mesurer la taille du DOM ?
Vous pouvez mesurer la taille du DOM de plusieurs manières. La première méthode utilise Lighthouse. Lorsque vous exécutez un audit, les statistiques sur le DOM de la page actuelle s'affichent dans l'audit "Éviter une taille DOM excessive" 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 mise à jour de la taille du DOM en temps réel, vous pouvez également utiliser l'outil de surveillance des performances. Cet outil vous permet de mettre en corrélation les opérations de mise en page et de stylisation (et d'autres aspects des performances) avec la taille actuelle du DOM.
Si la taille du DOM approche du seuil d'avertissement de Lighthouse ou ne répond pas aux critères, la prochaine étape consiste à trouver 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 effectuez le profilage d'une interaction lente dans le laboratoire et que vous pensez qu'elle peut ê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é dans le profileur intitulé "Recalculate Style" (Recalculer le style) et en observant les données contextuelles dans le panneau inférieur.
Dans la capture d'écran ci-dessus, vous pouvez voir que le recalcul de style de l'œuvre (lorsqu'il 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 travail de 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 du temps nécessaire pour que le frame suivant soit peint en réponse à une interaction.
Comment réduire la taille du DOM ?
En plus d'examiner le code HTML de votre site Web pour détecter les balises inutiles, la principale méthode permettant de réduire la taille du DOM consiste à réduire la profondeur du DOM. Un signe indiquant que votre DOM est peut-être inutilement profond est que vous voyez un balisage semblable à celui-ci dans l'onglet Éléments des outils pour les développeurs de votre navigateur:
<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. En particulier, les frameworks basés sur les composants, tels que ceux qui reposent sur JSX, vous obligent à imbriquer plusieurs composants dans un conteneur parent.
Cependant, de nombreux frameworks vous permettent d'éviter l'imbrication de composants en utilisant des fragments. Voici quelques exemples de frameworks basés sur des composants qui proposent des fragments en tant que fonctionnalité:
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 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 toujours être très volumineux et générer beaucoup de travail de rendu à mesure qu'il change en réponse aux interactions utilisateur. 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 se peut que de grandes parties de votre page ne soient pas initialement visibles par l'utilisateur lors du premier rendu. Il peut s'agir d'une opportunité de charger de manière différée le code HTML 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.
Cette approche est utile pendant le chargement initial et peut-être même après. Pour le chargement initial de la page, vous effectuez moins de travail de rendu à l'avance, ce qui signifie que votre charge utile HTML initiale sera plus légère et se chargera plus rapidement. Cela permettra aux interactions de s'exécuter plus facilement pendant cette période cruciale, avec moins de concurrence pour l'attention du thread principal.
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 le re-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 s'avérer délicat et présente ses propres compromis. Si vous optez pour cette méthode, vous envoyez 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 d'exécution ne soient pas comptabilisées dans l'INP, elles peuvent augmenter la latence perçue. Si possible, affichez une icône de chargement ou un autre indicateur indiquant que des données sont récupérées pour que les utilisateurs comprennent que quelque chose se passe.
Limiter la complexité des sélecteurs CSS
Lorsque le navigateur analyse les sélecteurs de 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 effectuer de travail pour effectuer le rendu initial de la page, ainsi que des recalculs de style et des travaux de mise en page supplémentaires 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'afficher de manière paresseuse les éléments DOM hors écran. À mesure que les éléments s'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'ignorer le travail de rendu des éléments hors écran lorsque le DOM de la page est modifié à la suite d'une interaction utilisateur.
Conclusion
Réduire la taille de votre 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 l'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 un sous-arbre DOM, comme la structuration CSS et la propriété CSS content-visibility
.
Quelle que soit la méthode que vous choisissez, en créant un environnement où le travail de rendu est minimisé, et en réduisant la quantité de travail de rendu effectuée par votre page en réponse aux interactions, votre site Web sera plus réactif aux utilisateurs lorsqu'ils interagiront avec lui. Cela signifie que votre site Web aura un INP plus faible, ce qui se traduit par une meilleure expérience utilisateur.