Fastify – le nom est la devise. Du moins, c’est ce que le framework pour Node.js veut représenter – la vitesse.
Après avoir constaté dans le dernier article que Node.js pur est clairement inférieur à Express, je me suis posé la question suivante : que peut-on utiliser d’autre pour développer des serveurs web rapides sans utiliser le module HTTP propre à Node.
Fastify m’est venu à l’esprit – j’ai donc écrit la même API trois fois – en Node.js pur, en Express.js, et en Fastify. Et maintenant, laissez-moi vous montrer comment Fastify se comporte face à la concurrence.
Commençons par écrire les API.
Installons d’abord Fastify
Comme d’habitude, nous faisons cela avec NPM : npm install fastify
Ensuite voici mon petit bout de code
const fastify = require('fastify') const app = fastify() app.get('/api', (req, res) => { res.send(`Bonjour ${req.query.name} ${req.query.name}`) }) app.listen(4000)
L’API Express.js
Pas si compliqué du tout. Et voici l’API Express.js, qui ressemble presque à la même chose npm install express
:
const express = require('express') const app = express() app.disable('etag') app.disable('x-powered-by') app.get('/api', (req, res) => { res.setHeader('content-type', 'text/plain') res.send(`Bonjour ${req.query.name} ${req.query.name}`) }) app.listen(4000)
Commentaires : Avec app.disable j’ai désactivé deux contenus dans l’en-tête, avant la réponse j’ai mis l’en-tête content-type
à text/plain
– dans Fastify c’est le défaut. Avec ces paramètres, nous obtenons des en-têtes presque identiques dans les trois APIs.
Native / Pur Node.js API
Enfin, le dernier, mais non le moindre, le serveur Node.js nu, complètement dépourvu de framework.
const http = require('http') const url = require('url') const app = http.createServer((req, res) => { const parsedURL = url.parse(req.url, true) if (parsedURL.pathname === '/api') { res.setHeader('content-type', 'text/plain; charset=utf-8') res.end(`Bonjour ${parsedURL.query.name} ${parsedURL.query.lastname}`) } }) app.listen(4000)
Dans Node.js pur, il n’y a pas de res.send
. J’ai ajouté l’instruction if pour être juste – après tout, les deux autres APIs vérifient la route lors de la demande. Sans l’instruction if, ce serveur Node répondrait à toutes les requêtes. Pour le content-type
, j’ai dû spécifier utf-8 manuellement. Avec Express et Fastfiy, cela était automatiquement dans l’en-tête. Ainsi, tous les en-têtes ont la même taille.
Le Benchmark
Pour le benchmark, j’utilise le MacBook Pro 15 pouces 2018, avec le processeur Intel i9 à 6 cœurs (2,9 GHz). Je me suis assuré que les mêmes conditions prévalaient dans tous les tests. Chaque serveur a été testé individuellement, toutes les autres sources de requête, à l’exception de l’outil de test de charge, ont été désactivées.
La version de Node.js est 16.13.1. J’ai simplement exécuté les APIs avec la commande node
, aucun PM2 ou nodemon
n’a été utilisé.
Le testeur de charge
J’ai décidé d’utiliser wrk. wrk est un outil moderne de benchmarking HTTP capable de générer une charge significative lorsqu’il est exécuté sur un seul CPU multi-core. Il combine une conception multithread avec des systèmes de notification d’événements évolutifs tels que epoll et kqueue.
Sous macOS, il peut être installé avec brew install wrk
. Sur Linux, il peut être installé avec sudo apt-get install wrk
.
Voici la commande que j’ai utilisée pour chaque API :
wrk -t12 -c400 -d10s "http://localhost:4000/api?name=Jean&lastname=Tremblay"
12 est le nombre de threads que nous utilisons, 400 le nombre de connexions simultanées. Le tout tourne pendant 10 secondes.
Les résultats
Bien sûr, j’ai bombardé chaque API plusieurs fois avec le testeur de charge – voici les résultats les plus moyens.
Express.js
Node.js pur / Natif
Fastify
Les résultats sont clairs – Fastify est plus rapide que Node.js même plus rapide que Express.js. C’est surtout ce dernier qui m’a surpris. Mais je l’ai aussi lu dans d’autres benchmarks, notamment sur le site officiel de Fastify. Il semble que ce soit le framework web le plus rapide dans le monde Node.js.
En résumé
En termes de performances, Fastify est supérieur.
Pour être juste, les benchmarks qui montrent de telles différences de performance sont souvent des situations très irréalistes – dans la réalité, pratiquement aucun serveur web ne serait bombardé par autant de demandes à la fois.
D’autant plus que le matériel du système joue également un rôle décisif. Malgré les performances supérieures de Fastify, je resterai principalement avec Express.
Pour moi et pour beaucoup d’autres, l’offre d’Express est tout à fait suffisante.
L’ensemble de l’écosystème est mieux équipé et il y a plus de ressources pour Express. Il est donc particulièrement adapté aux débutants.
Enfin, les différences entre les frameworks ne sont pas importantes pour de nombreux usages – notamment pour une API unique ou pour servir des ressources statiques, la migration vers un autre framework est facilement possible.
Par contre, cela reste dans les boîtes pour de futures intégrations. Voici le github pour le code de différents tests.