GraphicsMagick & performances avec Node.js
L’utilisation principale de la manipulation d’images sur internet, c’est de gérer les images uploadées par les visiteurs, pour les recadrer & créer des vignettes.
Pour ça, il existe quelques librairies très répandues, comme la librairie GD pour php, ainsi qu’ImageMagick ou GraphicsMagick, la seconde étant une fork de la première, les deux étant reconnues pour leurs performances.
Lorsque je suis passé à Node.js pour mes développements, il s’est naturellement posé la question de “Qu’est-ce que je vais bien faire pour mes manipulations d’images ?“
J’ai un peu creusé puis suis tombé sur le module gm, un package node pour manipuler de manière assez simple des images en passant par GraphicsMagick.
Et ça marche très bien.
Toutefois, dans le cadre d’un projet de site pour un client, je suis amené à prévoir une forte charge sur un site qui va permettre la manipulation d’image venant de tout type d’utilisateurs, et donc potentiellement être amené à traiter des images énormes (comme celles des appareils photos de maintenant avec leurs résolutions affolantes).
Mes premiers essais renvoyaient des chiffres assez bizarres, suffisament pour que je lance un (petit) protocole de benchmark : j’ai utilisé 4 fichiers images différents : un petit (un jpg en paysage de moins de 400px de large), un moyen (un jpg en portrait de 600px de haut), un grand (un png en paysage de 1920x1080px) et un énorme (un jpg plus ou moins carré de 4000px de côté).
Pour chacun, j’ai généré une vignette carrée de 100px (en rognant les bords qui dépassent) et une version redimenssionnée pour tenir dans une zone de 960 sur 720px.
J’ai lancé l’opération une centaine de fois pour chaque image, en utilisant le module npm gm.
Les temps moyens résultants ont été assez déroutants :
le petit est traité en 1 seconde
le moyen est traité en 1.2 seconde
le grand est traité en 4.1 secondes (!)
l’énorme est traité en 12.1 secondes (gloups!)
Si les deux premiers temps sont relativement acceptables dans le cadre d’un script d’upload, les deux derniers sont inconcevables !
J’ai donc décidé de créer un petit module npm qui ne servirait que de passerelle vers l’interface en ligne de commande de GraphicsMagick (ce que le module npm fait, mais en rajoutant des vérifications et contrôles).
Ce plugin, nommé lygrafmajik, ne fait vraiment que générer la commande et la transmettre au système via un child_process. Aucun contrôle, aucune vérification, et la doc de GraphicsMagick est là pour savoir quoi faire.
Mais les résultats du benchmark sont beaucoup plus décents :
le petit est traité en 0.4 seconde
le moyen est traité en 0.3 seconde (oui, je sais, c’est bizarre)
le grand est traité en 1.2 secondes (là, c’est tout de suite mieux)
l’énorme est traité en 0.9 secondes (et là, c’est vraiment peanuts)
Et paf!, ça fait des chocapics.
C’est sûr, il faut un peu lire de la doc, et celle de GraphicsMagick n’est pas la meilleure au monde, mais l’outil en lui-même est très puissant et permet de faire à peu près tout ce qu’on veut avec ses images.
Il n'y a pas de module de commentaires sur ce blog, principalement pour éviter à devoir gérer avec les spams, la pub, les insultes, ...
Toutefois, si vous avez quelque chose à dire/corriger/modifier, ou simplement exprimer votre opinion sur un post, n'hésitez pas à me contacter sur Twitter (@leny_be).