Depuis 2009, Node.JS et son gestionnaire de packages NPM, ont envahi les plates-formes de développement JavaScript. Essentiellement sur les serveurs, mais aussi pour les postes clients. Au-delà de son excellent et simplissime NPM, ce qui fait la différence avec les API Java EE ou .NET, c’est avant tout les remarquables (et supposées) performances d’une application Node, surtout quand elle est fortement sollicitée. Mais ce constat n’est-il pas de la poudre aux yeux ?

Un compromis codage – performances

Les gazettes et sites Internet sont truffés de comparaisons entre Node.JS et les autres plates-formes, essentiellement Java et .NET, avec quelques incursions dans le monde Ruby.

Et on nous ressort toujours la même explication, à savoir que pour Java EE, chaque requête émise par un client, donne lieu à l’instanciation d’un thread (ou process) mémoire, qui se cumule avec les autres, contrairement à Node qui se contente d’un seul thread qui se charge de répartir les demandes vers un pool de threads, extensible à l’infini.

Dans le premier cas, c’est excellent tant que l’on n’a pas une charge trop importante, mais ça coince avec des montées élevées, alors que dans le second, l’architecture est moins pénalisante et donne de bons résultats, justement pour des montées importantes. On pourrait aussi ajouter que Node est un serveur non bloquant, conçu pour des traitements asynchrones et qu’il libère les ressources d’E/S, dès lors qu’elles ont été sollicitées, voire ajouter que le moteur JavaScript V8 de Google, qui vient d’être mis à jour, sont des critères importants de performances.

Mais à y regarder de près l’explication n’est pas aussi simple et mérite que l’on s’y attarde.

Un modèle fondé sur les évènements

La vraie raison des performances de Node tient à ce qu’il met en œuvre un modèle d’exécution fondé sur les évènements, avec le pattern Proactor (conçu par Douglas Schmidt). Avec un tel modèle, déjà pratiqué sur le serveur HTTP nginx, concurrent d’Apache ou sur le framework Python Twisted, toute demande s’exécute dans un thread, mais à la différence du modèle multitâche de Java, ce thread commun ne fait que traiter l’évènement et passer la main à un autre process pour le réaliser, se libérant ainsi pour prendre en compte une autre demande. De plus, si ce process sollicité, pendant qu’il s’exécute, tombe en attente d’une E/S, il se libère pour faire « autre chose », selon le principe du service non bloquant.

En fait, le thread commun n’est rien d’autre qu’une grosse boucle de gestion des évènements, qu’il ne faudra surtout pas bloquer, car ce serait alors l’ensemble du mécanisme qui serait grippé.

On voit bien qu’un tel modèle ne peut donner de bons résultats que si les applications font une large part aux évènements, ce qui ne sera pas le cas d’une application synchrone et transactionnelle. L’avantage de Node est donc un fait avéré, mais il ne s’applique pas à n’importe quelle architecture applicative. On est dans le monde Web et on y reste… Là où tout ou presque est le résultat d’une action initiée par l’utilisateur demandeur ou par une autre application.

Un signe, les grands de ce monde ont choisi

On pourra toujours discuter à l’infini sur les avantages comparés des plates-formes, mais ce qui est sûr, c’est que plusieurs grands acteurs du monde Internet, ont déjà choisi Node pour supporter leur offre.

Ainsi LinkedIn est passé de RoR (Ruby) à Node, cheminement identique pour Microsoft, Yahoo !, Netflix, Twitter, Groupon ou Paypal, ce dernier en provenance de Java.

LinkedIn a précisé que le fait de passer à Node a multiplié les performances de son portail par 20, en plus des améliorations liées à une meilleure « scalability ».

Du côté de Netflix, même son de cloche, qui se dit très satisfait d’avoir réécrit son système avec Node, de même que Groupon, qui estime avoir divisé par deux, le temps de chargement de ses pages. Sans oublier la NASA, qui pense que Node est la solution la plus efficace, pour développer ses applications spatiales…

A notre niveau, il ne faut cependant pas prendre pour « argent comptant » les rodomontades des consultants, qui cherchent souvent à mettre en valeur la technologie qu’ils pratiquent le mieux et démontrent que Java et .NET sont plus rapides, mais aussi le contraire en faveur de Node. Pour des projets d’envergure, il faudra prendre le temps de faire un POC et sur ce POC de pratiquer les benchmarks les plus représentatifs des « workloads » à éventuellement prendre en charge.

Comme toujours, la réalité sera affaire de compromis et les architectures les plus performantes seront des mix de Java/.NET, de Node.JS, voire d’un autre framework sur le poste client.

Ce qui est sûr, c’est que la question se pose maintenant. Et nous suivrons en conséquence la publication des benchs qui ne manqueront pas d’intervenir ces prochaines semaines.