Qu'est-ce que le DOM ? Document Object Model expliqué
Le DOM est l'arbre d'une page web en mémoire dans le navigateur. Sa construction, sa modification par JavaScript et l'effet de sa taille sur la vitesse.
Qu'est-ce que le DOM ?
Le Document Object Model (DOM) est la représentation en mémoire d'une page web par le navigateur. Quand il analyse le HTML, le navigateur construit un arbre de nœuds (éléments, texte et attributs), et les scripts utilisent l'API du DOM pour lire et modifier la structure, le style et le contenu de cet arbre. Selon MDN, le DOM est une API web et ne fait pas partie du langage JavaScript lui-même.
Comment le navigateur construit le DOM
Le navigateur transforme les octets du HTML en caractères, puis en jetons, puis en objets, et relie ces objets en un arbre qui reflète les relations parent-enfant du balisage. Il fait de même avec le CSS et construit un autre arbre, le CSSOM. Ce sont deux structures indépendantes que le navigateur combine pour décider quoi afficher, ce qui explique qu'une page ne puisse pas s'afficher avant que son CSS soit connu. Le DOM n'est pas une copie littérale de votre source : il conserve les espaces comme nœuds de texte, et les scripts peuvent ajouter, déplacer ou supprimer des nœuds après le chargement. Le DOM que vous voyez dans les DevTools peut donc différer de « afficher le code source ».
Nœuds, éléments et API
Chaque objet de l'arbre est un nœud. L'élément est le type le plus courant, mais le texte et les attributs sont aussi des nœuds. L'objet document est la racine d'où l'on part. Prenons ce balisage :
<body>
<h1>Pricing</h1>
<p class="note">Billed monthly</p>
</body>Trois lignes de JavaScript le sélectionnent, le modifient et y réagissent :
const note = document.querySelector(".note"); // sélectionner le premier élément correspondant
note.textContent = "Billed yearly"; // modifier son texte
note.addEventListener("click", () => note.remove()); // réagir à un clic, puis le supprimerLes approches de rendu se distinguent surtout par l'endroit où le DOM est construit. Dans une application monopage, JavaScript en crée l'essentiel dans le navigateur. Avec un rendu côté serveur, le serveur envoie du HTML, le navigateur construit le DOM à partir de celui-ci, puis l'hydratation attache les gestionnaires d'événements.
Quand le DOM est-il prêt ?
DOMContentLoaded se déclenche une fois le HTML entièrement analysé et les scripts différés exécutés. Il n'attend ni les images, ni les sous-cadres, ni les scripts async ; l'événement load, plus tardif, marque la page entièrement chargée. MDN précise que c'est une erreur courante d'utiliser load là où DOMContentLoaded suffirait. Les scripts qui ont besoin d'éléments existants doivent utiliser defer, attendre DOMContentLoaded ou vérifier d'abord document.readyState.
Le DOM et la vitesse de la page
Chaque modification du DOM peut déclencher du travail de style, de mise en page et de rendu, et le coût croît avec la taille de l'arbre. Lighthouse avertit quand le body compte plus d'environ 800 nœuds et signale une erreur au-delà d'environ 1 400. Les grands arbres ralentissent le recalcul des styles et la mise en page, et les sélecteurs larges comme querySelectorAll("li") peuvent garder des milliers de références de nœuds en mémoire. Cela se voit dans la réactivité, donc dans l'Interaction to Next Paint (INP). Les éléments insérés tardivement sans espace réservé décalent en outre le contenu et pénalisent le Cumulative Layout Shift.
Erreurs courantes
- Écrire une saisie utilisateur avec
innerHTML. MDN le décrit comme probablement le vecteur le plus courant du cross-site scripting. UtiliseztextContentpour du texte brut. - Layout thrashing. Alterner dans une boucle des lectures du DOM comme
offsetWidthet des écritures de style oblige le navigateur à recalculer la mise en page à chaque tour. Regroupez d'abord les lectures, puis faites les écritures. - Interroger trop tôt. Un script dans
<head>sansdefers'exécute avant que le body n'existe :querySelectorrenvoie alorsnull. - Balisage profond et plein d'enveloppes. Aplatissez l'imbrication et utilisez flexbox ou grid plutôt que des conteneurs supplémentaires.
- Tout rendre d'emblée. Les longues listes et les sections masquées ajoutent des nœuds que personne ne voit encore. Chargez-les à la demande ou utilisez
content-visibility.
Le DOM dans les tests et le monitoring
Un test de charge au niveau protocole, comme ceux réalisés avec JMeter, envoie des requêtes HTTP et ne construit jamais de DOM : il ne dit donc rien du poids d'une page pour le navigateur. Il faut pour cela un vrai navigateur. Le LoadFocus Core Web Vitals Checker affiche les données de terrain d'une URL, dont la réactivité, et Page Speed Monitoring exécute des audits Lighthouse planifiés depuis 25 régions cloud (Lighthouse est l'outil derrière l'avertissement sur la taille du DOM évoqué plus haut). Pour améliorer l'INP, lisez How to Optimize Interaction to Next Paint (en anglais) et, pour configurer des alertes, How to Monitor Core Web Vitals (en anglais).
Questions fréquentes : Document Object Model
Le DOM fait-il partie de JavaScript ?
Non. Le DOM est une API web fournie par les navigateurs. JavaScript est le langage le plus courant pour l'appeler, mais le DOM est défini séparément.
Quelle différence entre le DOM et le code source HTML ?
Le code source est le texte envoyé par votre serveur. Le DOM est l'arbre vivant que le navigateur construit à partir de lui. Les scripts peuvent modifier le DOM après le chargement : les DevTools peuvent donc montrer des nœuds absents de « afficher le code source ».
À partir de combien de nœuds le DOM est-il trop gros ?
Lighthouse avertit à environ 800 nœuds dans le body et signale une erreur vers 1 400. Ce sont des seuils indicatifs, pas des limites strictes, et une page peut être lente en dessous si ses sélecteurs et sa mise en page sont coûteux.
Quelle différence entre DOMContentLoaded et load ?
DOMContentLoaded se déclenche quand le HTML est analysé et les scripts différés exécutés, sans attendre les images ni les scripts async. L'événement load arrive plus tard, quand la page est entièrement chargée.
Pourquoi innerHTML est-il risqué ?
Il interprète une chaîne comme du HTML : une saisie utilisateur non assainie peut alors exécuter du JavaScript malveillant via des attributs comme onerror. Utilisez textContent quand le contenu est du texte brut.
La taille du DOM influence-t-elle les Core Web Vitals ?
Elle peut le faire. Le travail coûteux de style et de mise en page causé par un grand DOM ralentit les interactions, ce qui compte dans l'INP, et les éléments insérés tardivement peuvent décaler la mise en page.
Termes associés
- First Contentful Paint (FCP) : définition, seuils et corrections
- First Input Delay (FID) : définition et remplacement par l'INP
- Image Size : Définition, Optimisation Web, Bonnes pratiques
- Qu'est-ce que la supervision d'infrastructure ?
- Qu'est-ce que JMeter ?
- Largest Contentful Paint (LCP) : définition, seuils et solutions
- Qu'est-ce que la latence ?
- Qu'est-ce que le lazy loading ?
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus, la plateforme même qui propulse tout ce que vous venez de lire.