En dehors du titre, le générique masculin est utilisé sans aucune discrimination et uniquement dans le but d'alléger le texte.

Javascript est utilisé en masse. Mais en vrai énormément de ceux qui l’utilisent n’ont aucune idée de comment ça marche cette affaire. Aujourd’hui je te parle single thread, event loop, callback queue, run-time et moteur Javascript. Et que tu sois junior ou un vieux de la vieille je suis sûr qu’en 5 minutes tu vas apprendre quelque chose. Sinon y’a toujours le mail en bas de page où tu peux m’envoyer directement des insultes.

Y’a quoi là-dedans ?

Alors je te dis tout de suite je vais pas t’apprendre à coder en Javascript. Tu me donnes cinq minutes, j’ai pas le temps. Non aujourd’hui je vais te parler de comment ça se fait que ton code Javascript il fonctionne tout court. Plus précisément on va parler de tout ce qui se passe une fois que ton DOM est chargé dans ton navigateur et que ton code Javascript est prêt à tout péter dans ta page.

Quand tu arrives sur une page des Internets tu utilises un browser comme Chrome, Firefox ou autre. Ils ont tous un moteur qui parse ton code et le convertit ensuite en commande exécutable dans un environnement d’exécution Javascript. Concrètement si on prend pour exemple le navigateur Chrome le moteur est le fameux moteur V8 et l’environnement d’exécution utilisé est Windows. Cet environnement d’exécution Javascript tourne dans un grand container. À l’intérieur duquel on trouve plusieurs autres plus petits containers.

We need to go deeper

Déjà dans le moteur Javascript on trouve deux choses : la première est la Memory Heap qui stocke et gère les variables et les déclarations de fonctions dans la mémoire. La seconde est la Call Stack qui est une structure de données qui parcoure la fonction en cours et établit un ordre d’exécution du code. C’est elle qui décide de ce qui est en cours d’exécution.

Hors moteur Javascript on trouve les Web APIs qui gèrent trois milliards de trucs comme les calls HTTPS, la manipulation du DOM et la gestion du timing. Un fetch ou un setTimeout par exemple c’est les WebAPIs qui sont responsables. Enfin on trouve la Callback Queue qui comme son nom l’indique est une file d’attente pour les callbacks. Elle va attendre que la Call Stack soit vide pour lui renvoyer des fonctions dans la gueule. Pour compliquer les choses certaines personnes utilisent les termes Message Queue ou même Task Queue pour parler de la Callback Queue.

Tout ceci se parle en utilisant l’event loop, c’est important on en parle en détail après. En attendant regarde j’ai fait un beau schéma pour que tu comprennes un peu mieux :

C’est fou les progrès que je fais sur ces schémas. Je vais t’expliquer comment tout ce beau monde se parle, mais avant il est important de comprendre que Javascript est un langage single thread. Ce terme barbare veut dire qu’il exécute une seule chose à la fois. Plusieurs processus d’exécution ne peuvent être faits au même moment. Imagine-toi que t’es à la poste le samedi matin avec un seul guichet ouvert. Et à la fenêtre du guichet, c’est Javascript qui traite chaque client un par un. Garde bien en tête que je parle ici du moteur Javascript.

Comment ils se parlent ?

Accroche-toi bien à ta chaise cette partie est cruciale pour comprendre le fonctionnement de Javascript. En Javascript on a beaucoup d’événements. Qu’ils viennent du navigateur (onload, onclose) du réseau (ajax, websocket) d’interaction (click, hover) ou du temps (timeout, interval) la plupart du code exécuté résulte de ces événements. Du coup il faut que quelqu’un surveille et dispatche sinon ça va être le bordel. Dans le rôle du chef de projet je te présente l’event loop.

En fait c’est simple l’event loop fait un while infini. Elle surveille en permanence la callback queue. Si elle voit une fonction en attente dans la file alors elle vérifie si la callstack est vide. Si oui elle pousse la fonction dans la callstack sinon elle attend que la callstack soit vide pour le faire. Et ainsi de suite de façon infinie pour tout le code que tu voudrais lui faire exécuter. Il est important de noter que chaque tab de ton navigateur à son propre environnement avec sa propre event loop. L’event loop est une machine de guerre qui tourne en boucle, qui est partout et qui ne s’arrête jamais.

Vraiment single thread ?

Maintenant se pose la question de la concurrence et des opérations bloquantes. Comment je peux soutenir que Javascript ne sait faire qu’une chose à la fois quand tu peux process une belle animation en faisant un long call HTTP asynchrone en même temps ? C’est simple : le runtime Javascript process ton animation pendant que les WebAPIs du navigateur font le call HTTP. En fait tu fais bosser ton browser pour le call HTTP, pas Javascript. Une fois que les WebAPIs ont fini d’aller fetcher ton call l’exécution du résultat (la callback de ta fonction) est mis dans la callback queue. L’event loop intervient alors quand la call stack est vide et met la fonction dans la call stack déclenchant son exécution.

Si tu as un peu de temps devant toi (quand même 25 min) je te conseille fortement de regarder cette conférence de Philip Roberts. C’est le meilleur et plus complet résumé de Javascript que j’ai jamais vu.

La majorité de ce qui passe en Javascript passe par l’event loop qu’on vient d’évoquer. Ce qui est intéressant de comprendre c’est la philosophie non bloquante de Javascript. Si tu codes pas avec ton cul tu vas faire attention que tout processus long soit fait de façon asynchrone. Typiquement ça va prendre la forme d’événements, promesses et callbacks. Pendant que ces process longs sont faits en background ta callstack est libre et peut process des choses. Ton programme ne bloque jamais. Enfin, encore une fois, si tu fais attention à ce que tu fais. Fais un gros while de 1 à 10 milliards tu vas voir que Javascript va bloquer ta tab comme un gros sale sans problème.

Épilogue

Si tu utilises NodeJS en backend comme moi, tu peux remplacer les WebAPIs par la librairie C++ libuv et le fonctionnement est le même. C’est court cinq minutes, mais j’ai pu te parler de la base du fonctionnement de Javascript. Tu te doutes bien que y’en a plus sous le capot. Par exemple les tâches et micro-tâches. Si tu veux aller plus loin je te conseille fortement la lecture de ce bouquin. Ceci dit ce résumé va déjà t’aider à mieux comprendre l’envers du décor de ton code. Et ça risque de fortement t’aider face à un bug incompréhensible ou pour optimiser ton app.