Dans les entrailles du Dom Virtuel

Nicolas KOKLA
5 min readMar 23, 2017

--

Photo by Ousa Chea on Unsplash

De même que Tim Berners Lee n’avait probablement pas imaginé que le World Wide Web évoluerait d’une plateforme de partage documentaire vers une distribution d’applications décentralisées, lorsque Brendan Eich créa le JavaScript en 1995, je doute qu’il avait imaginé ce que deviendrait ce langage de script volontairement limité.

Nous sommes en 2017 et la percée de React dans l’industrie du Web ne fait plus aucun doute. Lorsque Facebook a présenté sa librairie de gestion et de manipulation d’interface, il a surtout présenté un nouveau paradigme. Là où la plupart des autres outils du marché (AngularJS ou Ember par exemple) ont visiblement cherchés à optimiser le travail du développeur et la production des applications en s’approchant d’une conception type ‘Web Components’, React s’est avant tout tourné vers la performance en prenant en compte les lacunes de nos navigateurs. Et la première d’entre elle, aussi paradoxale soit-elle, est le rendu et la manipulation de l’arbre DOM en page web. Pour compenser cette faiblesse, les développeurs de React ont intégré ce que l’on nomme un DOM virtuel.

Ce DOM Virtuel est une version miroir du DOM réel, placé en mémoire, et sur lequel ont effectuera nos manipulations avant de les envoyer vers le navigateur. C’est un élément de la Bibliothèque React dont on entend régulièrement parler, sans pour autant expliquer comment il est mis en place. Je vous propose donc de voir ça d’un peu plus près en créant notre propre DOM virtuel.

Mais au fait, c’est quoi le DOM ?

Oui, parce qu’un petit rappel s’impose probablement pour certains d’entre vous.

Le ‘DOM’, ou “Document Object Model” (autrement dit le “Modèle à Objet d’un Document”) est une Interface de programmation donnant accès à la représentation de notre page Web (ou tout autre document HTML ou XML) sous forme d’une structure d’objets qui composent le document (autrement dit, la page Web).

Ou encore, reformulé de façon plus détaillée :

Le DOM…

· Est une Interface de programmation… (API)
· Donne accès à la représentation de notre page Web… (Ou tout autre document HTML ou XML)
· Contient des objets… (Tel qu’entendu en programmation : avec des propriétés et des méthodes)
· Est structuré de manière organisée… (Le Modèle, à savoir : l’arbre des éléments qui composent la page web)

Les API DOM (implémentées par Netscape et Microsoft en 1997) sont, dès leurs origines, accessible via JavaScript ou ses équivalents (comme le JScript des anciens navigateurs de Microsoft). Mais leur standardisation par le W3C et l’application de ce standard mettra un peu de temps à être appliqué, notamment sur Internet Explorer qui domine alors le marché.

Aujourd’hui les API DOM ont été largement démocratisées par des bibliothèques comme JQuery qui avaient pour principal avantage, en plus de la simplification, d’effacer les différences d’implémentation. Ces bibliothèques sont si utilisées, que certains développeurs en ont même oubliés comment accéder à l’API de façon native.

Avant JQuery ou le DOM virtuel, il y avait le DOM…

L’exploitation de l’API DOM via le JavaScript natif, repose sur quelques méthodes et propriétés régulièrement utilisées comme document.getElementById(id) ou element.innerHTML.

Prenons un exemple simple :

Nous allons écrire un composant très simple, capable d’afficher un titre et un contenu (un peu comme un post de commentaire). Ces titres et contenus seront fournis dynamiquement et pourront aussi bien être du texte que du code HTML. L’objectif de cet exercice est uniquement didactique, et pour cette raison, j’ai essayé de fournir le code le plus simple possible.

Dans cette première étape, on utilise les API natives de JavaScript pour accéder au DOM de la page : On cible des éléments avec ‘document.getElementById(id)’ puis on y accède et les modifie avec ‘element.innerHTML’.

C’est extrêmement simple et assez propre, mais on constate vite que c’est assez éloigné de l’esprit ‘Web Components’ porté par la plupart des frameworks du moment. Ceci est principalement dû au fait que le code du Template de notre composant est uniquement porté par notre code HTML.

Qu’à cela ne tienne…
Ajoutons un système de Template…

Le code HTML du composant est maintenant bien porté par notre code JavaScript. Pour autant nous continuons à déléguer la construction, par le navigateur, de l’arbre DOM au moment du rendu.

En effet, l’usage, certes confortable, de ‘innerHTML’ implique des étapes supplémentaires au navigateur :

En plus du nécessaire ‘Reflow’, c’est-à-dire le placement des blocs sur la page en fonction des autres blocs présents -l’une des étapes les plus longues lors d’une construction de page Web-, une étape de construction d’arbre DOM sera imposée.

En effet ‘innerHTML’ ne prend pas en entrée des éléments DOM mais du code HTML sous forme de chaine de caractères. Ce code HTML doit être convertit avant de pouvoir être intégré à l’arbre DOM de la page et c’est justement ce que fait ‘innerHTML’. Mais ici, on le fait directement lors de l’intégration. De plus, le code HTML fournit n’est pas manipulable, autrement qu’en chaine de caractère, avant cette conversion : si on a besoin de lire une donnée de ce code HTML, on devra soit ‘parser’ la chaine de caractère (ce qui est loin d’être confortable), soit relire directement ce qui a été ajouté dans le DOM de la page Web… C’est ici que la mise en place d’un DOM Virtuel prend tout son sens…

Mise en place du DOM Virtuel

Dans le code ci-dessus, la variable ‘vDom’ contient notre DOM virtuel. Toutes les manipulations du DOM se feront à l’intérieur de ce nœud. Or ce nœud est en mémoire et n’est jamais directement intégré dans notre page. Cela permet de déléguer tous les traitements qui peuvent avoir lieu uniquement sur la mémoire, sans jamais nécessiter de rendu par le navigateur, hormis lors de l’étape finale d’injection.

Mais tout n’est pas parfait. En effet, le contenu est entièrement actualisé à chaque frappe. Hors, dans l’idéal, il ne faudrait actualiser que les nœuds qui ont changés. Cela est particulièrement visible si vous injectez une vidéo pour le ‘contenu’ et que vous modifiez le titre. C’est là qu’intervient ce que nous verrons dans la prochaine partie de ce tutoriel ; le second élément du DOM Virtuel : Le Diff-Dom, autrement dit, le calcul du différentiel entre deux arbres DOM…

--

--

Nicolas KOKLA

Lead Dev Front End // JavaScript Full Stack // Front End Architect // Mindset: “Coding better, harder, stronger” // hobbys: “Gamer better, harder, stronger”