Node.js est une plateforme logicielle avec une architecture orientée événements qui permet d’utiliser le langage de script JavaScript, initialement développé pour une utilisation côté client, pour une utilisation côté serveur. Cela fonctionne comme PHP, Java, .NET, Ruby ou Python pour écrire du code pour le serveur. Il est utilisé pour le développement d’applications JavaScript côté serveur qui doivent assumer de fortes charges en temps réel. L’environnement d’exécution est apprécié pour la réalisation de serveur Web léger.
La plateforme logicielle, qui a été pensée en 2009 par Ryan Dahl, se base sur le moteur V8 du JavaScript de Google qui intervient aussi sur le navigateur Web Chrome. Lancé par l’entreprise Joyent, le projet dépend depuis 2015 de la fondation Linux sous le nom de Node.js Foundation. Des versions actuelles sont disponibles pour Microsoft Windows, Mac OD, et Linux.
Node.js comprend une librairie de modules JavaScript divers, qui peuvent être chargés grâce à une fonction simple et servir directement comme élément structurel pour le développement d’applications Web. Un exemple est le module HTTP, qui permet grâce à une fonction unique de créer un serveur Web rudimentaire. En outre, le package intégré (dit « NPM » pour Node Package Manager) permet d’installer des modules complémentaires.
L’avantage majeur de Node.js est son architecture orientée événements, avec laquelle un code de programme s’exécute de manière asynchrone. Node.js est donc basé sur un seul fil d’exécution et un système entrée/sortie (ou I/O pour Input/Output) qui permet un traitement parallèle de plusieurs opérations d’écriture et de lecture.
- I/O asynchrone : parmi les tâches classiques effectuées par un serveur, on compte la réponse aux requêtes, la sauvegarde de données dans une base de données, la lecture de fichiers depuis le disque dur, ou encore l’établissement de connexions vers d’autres composants du réseau. Ces activités sont désignées comme sortantes/entrantes. Les opérations entrantes/sortantes sont exécutées de manière synchrone dans des langages de programmation tels que C ou Java. Ainsi, les tâches sont effectuées les unes après les autres. Cela signifie que le système I/O est bloqué tant que la tâche en cours n’est pas terminée. En revanche, Node.js utilise un I/O asynchrone, qui délègue les opérations d’écriture ou de lecture directement au système d’exploitation ou aux bases de données. Ceci permet de travailler sur un grand nombre de tâches en parallèle sans avoir de blocage. Les applications basées sur Node.js et JavaScript présentent ainsi l’énorme avantage de gagner en rapidité dans de nombreux cas de figure.
- Fil d’exécution unique : pour compenser le temps d’attente dans les I/O synchrones, des applications serveur basées sur des programmes de langage classiques orientés serveurs s’appuient sur plusieurs threads (avec les inconvénients du multithreading). Ainsi, un serveur Apache HTTP commence par exemple un nouveau fil à chaque requête détaillée. Le nombre de fils possibles (et donc aussi le nombre de requêtes qui peuvent être traitées parallèlement dans un système multi-threadé synchrone) est limité par l’espace mémoire disponible. Node.js en revanche ne fait intervenir qu’un fil d’exécution du fait du system I/O décentralisé ce qui permet de réduire considérablement la complexité mais aussi l’exploitation des ressources.
- Architecture orientée événements : l’exécution asynchrone d’opérations I/O est réalisée grâce à l’architecture orientée évènements de Node.js. Il se base en réalité essentiellement sur un seul fil (mono-thread) qui se trouve sur une boucle d’évènements. Cette dernière a pour mission d’attendre des évènements et de les gérer. Les évènements sont alors classés en tant que tâches ou résultats. Si la boucle enregistre une tâche, par exemple une requête de base de données, cette dernière va être mise en arrière-plan du processus avec ce que l’on appelle une fonction de rappel (Callback). Le traitement de la tâche n’a pas lieu sur le même fil sur lequel la boucle fonctionne, ce qui permet à cette dernière de passer immédiatement à l’événement suivant. Si une tâche transférée est exécutée, les résultats du processus transféré sont retournés à la boucle comme nouvel évènement grâce à la fonction callback. Par conséquent, la boucle peut déclencher la remise du résultat.
Ce modèle non bloquant orienté évènement a l’avantage de ne jamais laisser inactive l’application sur Node.js en attendant un résultat. Il est ainsi par exemple possible d’exécuter différentes requêtes des bases de données simultanément sans que le programme ne soit retardé. L’établissement d’un site, qui exige différentes requêtes externes, se déroule bien plus rapidement avec Node.js qu’avec un processus de traitement synchrone.