DEV Community

Cover image for Comprendre le DOM (Document Object Model)
Robin Blanquart
Robin Blanquart

Posted on • Edited on

Comprendre le DOM (Document Object Model)

Les origines du DOM

À la fin des années 90, chaque navigateur avait sa propre façon d’interagir avec les pages HTML. C’était un vrai casse-tête pour les développeurs, il fallait parfois écrire plusieurs versions d’un même code selon que l’utilisateur était sur Internet Explorer ou Netscape, par exemple. (j'ai dû rappeler quelques souvenirs de jeunesse à certains)

Pour sortir de cette impasse, la W3C (World Wide Web Consortium), organisme chargé de standardiser les technologies web, a proposé en 1998 une première version appelée "DOM 1". L’objectif était d'uniformiser la manière d’accéder et de modifier les documents HTML à travers tous les navigateurs.


Comment fonctionne le DOM concrètement ?

Quand tu ouvres une page web, ton navigateur envoie une requête HTTP (HyperText Transfer Protocol) pour récupérer du HTML. Mais ce HTML, c’est une chaîne de caractères brute. Le navigateur doit donc le transformer en une structure exploitable.

HTTP request client to server


Étape 1 : La tokenization

Un "tokenizer", c'est un script qui va venir modifier un input pour donner une forme différente à la sortie. Dans notre cas le tokenizer lit le HTML brut, caractère par caractère pour générer des tokens. Chaque token correspond à une entité sémantique comme une balise ouvrante, un attribut, du texte, etc...

Étape 2 : Le Tree Builder

Ces tokens sont ensuite traités par le tree builder. C’est lui qui construit une structure arborescente à partir des tokens. Cette structure en mémoire est ce qu’on appelle le DOM.

Chaque navigateur a son propre moteur de rendu, qui contient le tokenizer, Chrome utilise "Blink" et fonctionne en C++ uniquement, pour Firefox c'est "Gecko" qui lui fonctionne en C++ / Rust

Et le CSS dans tout ça ?

Le CSS est également analysé pour former une structure équivalente, le CSSOM (CSS Object Model). Ensuite, le DOM et le CSSOM sont fusionnés dans ce qu’on appelle le Render Tree, qui permet au navigateur de calculer ce qu’il doit réellement afficher à l’écran.

Schéma du fonctionnement de la tokenization et de la création du 'render tree'

C’est justement parce que les moteurs de rendu diffèrent d’un navigateur à l’autre et que les spécifications pour le CSS restent trop permissives qui explique les différences de styles qu'on peut avoir sur chacun des navigateurs.


Le DOM et ses noeuds

Le DOM prend la forme d’un arbre de noeuds. Chaque élément (balise, texte, commentaire..) est un noeud. Tous héritent d’une interface commune appelée "Node".

Tu as peut-être déjà remarqué que chaque type de noeud a un identifiant (de 1 à 12), mais seulement quelques-uns sont réellement utilisés en HTML moderne :

Identifiant Nom Description
1 ELEMENT_NODE Une balise HTML (<div>, <h1>, etc..)
2 ATTRIBUTE_NODE Un attribut HTML (class, style..)
3 TEXT_NODE Le texte brut dans un élément
8 COMMENT_NODE Un commentaire HTML
9 DOCUMENT_NODE Le document racine (le seul noeud à ne pas avoir de parents)
10 DOCUMENT_TYPE_NODE Le <!DOCTYPE html>
11 DOCUMENT_FRAGMENT_NODE Un conteneur temporaire pour manipuler des groupes de noeuds

Les autres types sont liés à XML ou rarement utilisés dans un contexte web.

Si on voulait représenter concrètement la forme des noeuds pour une simple balise <p> voici à quoi cela ressemblerait :

Document
 ├── DocumentType            <!DOCTYPE html>
 └── HTMLHtmlElement         <html>
      └── HTMLBodyElement    <body>
          └── HTMLParagraphElement  <p>
              └── TextNode          "Coucou"
Enter fullscreen mode Exit fullscreen mode

Des objets C++... mais manipulés en Javascript ?

On parle souvent du DOM comme s’il s’agissait d’objets Javascript. C’est faux (ou du moins, trop simplifié).

En réalité, les noeuds du DOM sont des objets C++ créés et gérés par le moteur du navigateur. Petite nuance, ce ne sont pas les tokenizers eux-mêmes qui créent les objets C++, mais bien le tree builder, à partir des tokens.

Schéma pour décrire le principe de 'tree builder' et 'render tree'


Alors comment JS y accède ?

C’est là qu’intervient un concept important, le glue code.

Le glue code, c’est un programme intermédiaire qui permet de faire le lien entre deux modules qui normalement n'intéragissent pas ensembles, ici, C++ et Javascript. Il agit comme une passerelle, tu écris du Javascript, mais en réalité, ce code envoie des instructions aux objets C++ du DOM.

  • Dans Chrome, c’est le moteur Javascript V8 qui gère cette liaison.
  • Dans Firefox, c’est SpiderMonkey.

Schéma explicatif du glue code


Quelques API natives du DOM

Le DOM fournit également un ensemble d’API natives très utiles pour observer ou réagir aux changements d’état dans la page.

Petit tour rapide ici, mais chaque API pourrait mériter un article complet.

  • MutationObserver : détecte les changements dans la structure du DOM
  • IntersectionObserver : détecte quand un élément entre/sort du viewport
  • ResizeObserver : observe les changements de taille d’un élément
  • requestAnimationFrame : synchronise et optimise les animations

Performances et optimisation

Si tu as déjà touché à React ou Vue, tu as sûrement entendu parler du Virtual DOM. Il s’agit d’une copie en mémoire du DOM qui permet de simuler des changements, puis d’appliquer uniquement les modifications nécessaires au vrai DOM.

Mais alors pourquoi j'en parle ici ?


Le DOM peut être coûteux.

Prenons un exemple simple, tu modifies la couleur et la position d’un élément <p>. Voici ce qui peut se produire :

  • Style recalculation : le navigateur applique les nouvelles règles CSS.

  • Reflow : il recalcule la position et la taille de l’élément, ce qui peut affecter d’autres éléments.

  • Paint : il redessine les éléments qui ont un changement de couleur.

  • Composite : il assemble les calques pour produire le rendu final (z-index, transform, etc...)

Et il faut t'imaginer cela sur des dizaines voire des centaines de noeuds et en quelques secondes.. ça fait un paquet de boulot.

Bonne nouvelle, si tu modifies juste la couleur, seul le paint sera déclenché. Le navigateur optimise déjà cette partie là mais cela reste toujours très gourmand.


Comment optimiser tout ça ?

La performance avec le DOM, c’est un sujet très important. Elle repose sur :

  • Une architecture solide
  • L’assimilation de bonnes pratiques
  • Une compréhension importante du fonctionnement du DOM (tu es au bon endroit)

Voici quelques techniques d'optimisation :

  • ✅ Éviter les boucles qui modifient le DOM à répétition
  • ✅ Utiliser DocumentFragment pour grouper les noeuds
  • ✅ Utiliser requestAnimationFrame pour les animations
  • ✅ Privilégier les canvas pour les rendus complexes

Mais cela ne représente qu'une infime partie des optimisations possibles avec le DOM, des dizaines d’approches sont possibles pour améliorer les performances.


Conclusion

Le DOM n’est pas juste une liste d’objets Javascript manipulables dans la console. C’est une interface exposée par ton navigateur pour accéder à des structures C++ internes.

Comprendre cette architecture permet de casser un mythe courant, le DOM n’est pas du Javascript. Ce sont des objets C++ que tu appelles avec ton code JS, avec un gros processus de calculs à chaque modification.

Le sujet du DOM est très vaste, il reste beaucoup de concepts (Shadow DOM, VDOM, DOM Diffing) à voir et qui auront totalement leur place dans un article prochain 😉


Si on ne se connaît pas encore, moi c’est Robin, développeur web depuis +5 ans. Je publie ici des articles pour t’éclairer sur l’univers du web et comprendre les technologies en profondeur. 😉

Si tu veux en savoir un peu plus sur moi, c'est par ici 👇

📮 𝘾𝙤𝙣𝙩𝙖𝙘𝙩 : rb.blanquart@gmail.com
💼 𝙇𝙞𝙣𝙠𝙚𝙙𝙞𝙣 : https://www.linkedin.com/in/robin-blanquart-44107122b/
👀 𝙋𝙤𝙧𝙩𝙛𝙤𝙡𝙞𝙤 : https://robin-blanquart.com/

Top comments (0)