EcrituresNumeriques / stylo

Stylo est un éditeur de textes pour articles scientifiques en sciences humaines et sociales.
https://stylo.huma-num.fr
GNU General Public License v3.0
52 stars 13 forks source link

Utilisation de lean et de dataloader afin d'améliorer les performances #864

Open ggrossetie opened 1 year ago

ggrossetie commented 1 year ago

Les modèles Mongoose sont assez pratiques mais impactent rapidement les performances. Je pense qu'il est préférable d'utiliser lean avec https://github.com/graphql/dataloader afin de mieux maitriser les requêtes envoyés à MongoDB et ainsi améliorer les performances.

À terme il sera envisageable de remplacer Mongoose par le driver MongoDB officiel: https://mongodb.github.io/node-mongodb-native/index.html (puisqu'on ne dépendra plus des fonctionnalités d'ORM/ODM de Mongoose).

Un premier travail a été initié sur la branche "workspace" (espace de travail).

thom4parisot commented 1 year ago

Est-ce qu'il y a un chemin pas à pas ? Ou tester sur la liste articles pour voir que ça résoud bien le temps de chargement ?

ggrossetie commented 1 year ago

Je teste sur le compte d'Antoine (sur stylo-dev) qui a quasiment 300 articles, la requête GraphQL prend maintenant 300-400ms:

image

Sur le poste d'Antoine le rendu complet de la page prend 2 secondes. Je pense que le gain est assez notable :

stylo-dev : 14 secondes pour 173 articles, avec un ordinateur relativement récent et puissant stylo-prod : 4 secondes pour 172 articles, même situation

Il y a peut être encore des petites choses à améliorer notamment sur le rendu de la page et peut être des chose à tweak côté MongoDB/Mongoose.

ggrossetie commented 1 year ago

Ce qui est bizarre c'est que la liste des articles affiche 173 articles.... il doit y avoir des articles sur lesquels il est propriétaire ET contributeur (ce qui ne devrait pas arriver en théorie).

Ou alors mes stats sont fausses ou comme on utilise des relations bidirectionnelles il manque peut être des articles (ou il y a des articles en trop) dans users.articles 😄

thom4parisot commented 1 year ago

Woah, incroyable ! Merci pour les chiffres et d'avoir trouvé cette solution 🙂

ggrossetie commented 1 year ago

Dans les "pièges" de dataloader il faut bien faire attention que ça soit le même tick de l'event loop. Ce qui semble bien fonctionner c'est les array.map(item => dataloader.load(item._id)) au final ça va faire une seule requête avec l'ensemble des identifiants. Il y a aussi une notion de cache mais pour le moment je suis la recommandation d'une instance de dataloader par requête:

Avoid multiple requests from different users using the DataLoader instance,