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 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 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 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 opérations de mise en page coûteuses peuvent avoir une incidence sur l'INP (Interaction to Next Paint). Si vous souhaitez qu'une page réponde rapidement aux interactions des utilisateurs, il est important de vous assurer que les dimensions de vos DOM ne sont pas suffisantes.
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 de 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 ont plusieurs conséquences sur les performances des pages :
- Lors du rendu 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 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 opérations de mise en page, de stylisation, de composition et de peinture très coûteuses. 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 mémoire peut être considérable si le résultat renvoie un grand nombre d'éléments DOM.
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 concernant le DOM de la page actuelle sont incluses dans l'audit "Éviter une taille de 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 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.
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 profilez une interaction lente dans l'atelier qui, selon vous, a un rapport avec la taille du DOM de la page, vous pouvez déterminer le nombre d'éléments DOM affectés en sélectionnant n'importe quelle activité dans le profileur intitulée "Recalculate Style" (Recalculer le style), puis en observant les données contextuelles dans le panneau inférieur.
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 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 ?
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. 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 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 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 assez 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.
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 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, la charge 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 choisissez 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
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. 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 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.