Vous avez détecté que votre backend était trop lent ? Qu’il pénalisait la vitesse de chargement de votre site web ? Pas de panique, il s’agit d’un problème de Webperf très fréquent. Je vais tenter dans cet article de vous guider dans l’identification des problèmes, puis vous fournir quelques tuyaux pour les corriger.
Mais qu’est-ce qu’un backend trop lent ? Mon conseil est de ne jamais avoir un Time to First Byte (mesuré avec WebPageTest en connexion « Cable ») supérieur à 600 millisecondes, réseau inclus. Et si les performances sont vraiment importantes pour vous, tentez de passer sous la barre des 300ms.
Note : cet article est destiné à des lectrices et lecteurs de niveau technique intermédiaire. Cependant, même si ce n’est pas votre cas, la partie consacrée au hardware pourrait vous intéresser.
Première affirmation de cet article : ne vous précipitez pas immédiatement sur un serveur plus puissant. Bien sûr un hardware qui dépote peut vous faire gagner des millisecondes, mais de nombreux problèmes de performances proviennent du software : un code trop lourd, des requêtes vers une API externe, une base de données mal configurée… et bien d’autres.
Je vais d’ailleurs vous confier un secret. De nos jours, la plupart des sites présents sur le web sont lents, très lents. Mais… ils trichent !
Un cache externe à la rescousse
Comment trichent-ils ? Grâce une stratégie de cache forte.
Le serveur depuis lequel vous lisez cette page, par exemple, est un bon vieux (et lent) WordPress qui ne sait pas répondre en moins de 500ms. Sauf qu’il est couvert par un cache externe capable de répondre beaucoup plus rapidement.
Qu’est-ce qu’un cache externe ? Il s’agit d’une mémoire qui stocke des pages entières, de façon à pouvoir les resservir presque instantanément la prochaine fois qu’un visiteur en a besoin.
Vous pouvez monter votre propre cache grâce à ce qu’on appelle un serveur « reverse proxy ». Les plus connus sont gratuits et open-source :
Autre solution, vous pouvez payer pour un CDN (Content Delivery Network), qui agira comme un « supercache ». Il apporte le cache au plus près de vos utilisateurs grâce à un réseau de machines disposées un peu partout à travers le monde. Je recommande plus particulièrement leur utilisation lorsqu’une partie de vos utilisateurs sont situés à plus de 3000km de votre serveur. En prime, un CDN vous protège des attaques de type DDoS.
Mes deux services de CDN préférés sont :
- KeyCDN (gagnez 10US$ de crédits via ce lien)
- CloudFlare (avec une offre gratuite pour les petits sites à but non lucratif)
Le cache a un effet négatif : il limite les modifications en temps réel. Imaginons que vous ayez mis en place un cache avec un TTL (durée de persistance) de 2 heures. Les changements que vous ferez sur votre site risquent de mettre jusqu’à 2h pour être visibles des utilisateurs. Toute la difficulté est de trouver le juste milieu entre votre besoin de réactivité et le nombre d’utilisateurs qui tomberont sur un cache expiré.
L’utilisation d’un cache peut aussi présenter des difficultés dans certains cas :
- si l’information doit réellement être fraîche à la seconde près,
- si le contenu de la page est personnalisé,
- si la plupart de vos utilisateurs sont loggés,
- si le code HTML du panier d’achat est géré côté backend,
- …
Et le cache interne ?
La mise en cache n’est pas seulement utile pour des pages HTML finales, elle peut aider à accélérer le langage backend en stockant des bribes de data.
Quelques exemples d’utilisation d’un cache interne :
- Si chaque page demande à la base de données le nombre de clients satisfaits depuis la création d’une boutique, mettez en cache la réponse afin d’éviter cette lourde requête.
- Si votre menu de navigation est lourd et généré à partir d’une douzaine de requêtes dans la base de données, stockez en cache le bout d’HTML généré.
- Si votre application appelle une API externe pour récupérer les taux de change tout frais, envoyez en cache cette réponse aussi, même si c’est juste pour une minute.
Une fois que vous commencerez à mettre en cache, vous ne pourrez plus vous arrêter parce que c’est finalement très simple. Souvenez-vous juste d’ajouter un mode « cache désactivé » sur votre appli, autrement le débogage peut vite tourner au cauchemar.
Enfin, et c’est l’un des points les plus importants, vérifiez que votre cache interne est rapide. Le critère le plus important est où les données sont stockées physiquement. Par exemple, le cache par défaut du CMS Drupal stocke en base de données. C’est mieux que rien, mais lire depuis une BDD est 10x plus lent que depuis le disque dur, lui-même 10x plus lent que depuis la mémoire vive.
Personnellement j’utilise Memcached sur mes projets, un système open-source de cache en mémoire vive, sobre et efficace. Vous pouvez aussi jeter un œil à Redis, un tout petit peu plus lent mais doté de plus de fonctionnalités (stockage de données structurées, persistance sur le disque dur, sécurité…). Ces deux outils possèdent des connecteurs pour quasiment tous les langages et tous les frameworks backend.
Les profilers savent tout de votre backend
Relevez vos manches, enfoncez votre casque, nous allons maintenant entrer dans la machine.
Un profiler est un outil qui instrumentalise votre langage backend afin de mesurer à peu près tout ce qu’il est possible de mesurer. Il est alors capable de fournir des statistiques sur les fonctions ou les composants les plus lents, les requêtes à la base de données ou encore les requêtes externes. Parfois même, il est capable de fouiller dans les obscurs paramètres du serveur pour proposer une amélioration de son paramétrage.
Si vous avez une machine de test similaire à votre site en ligne, il vaut mieux profiler sur celle-ci pour éviter de déranger le site. Sinon, je recommande de toujours le désactiver une fois les optimisations terminées, car l’instrumentalisation engendre un léger surcoût dont on se passera volontiers.
Note : si votre site est hébergé sur un serveur partagé, vous ne serez probablement pas autorisés à « entrer dans la machine ». Vous pouvez tenter de profiler votre appli sur un serveur local, ou bien vous pouvez scroller directement au chapitre concernant le hardware.
Le plus connu des outils de profilage est New Relic. Il gère des douzaines de langages et sait à peu près tout faire. Je vous suggère de souscrire à son offre d’essai de 30 jours qui laisse suffisamment de temps pour diagnostiquer les problèmes et les corriger.
Dans le monde PHP, BlackFire fait un bon travail (15 jours d’essai). Tideways aussi, paraît-il, mais je n’ai pas testé (30 jours d’essai).
JProfiler est populaire pour le langage Java et Rack Mini Profiler pour le Ruby. Le langage Python inclut son propre profiler appelé cProfile, tout comme Node.js. Enfin, si vous utilisez Shopify, l’équipe a récemment sorti un Theme Inspector.
Voyons maintenant comment réagir selon les lenteurs que vous détecterez.
Que faire si la base de données est trop lente ?
Si le profiler indique que la base de données est une cause importante de ralentissements, je vous conseille de vous pencher sur les points suivants :
- le nombre de requêtes nécessaires à la création d’une page : tentez de le réduire par tous les moyens (le cache interne est votre ami).
- les requêtes les plus lentes : cherchez à les réécrire ou à modifier les index de vos tables.
- les requêtes répétées sur la même table : tentez de les regrouper en une seule « bulk request ».
Pour aller plus loin, il existe des outils de profilage de base de données. La solution tout-en-un de New Relic l’inclut dans son package, sinon, vous trouverez facilement d’autres outils. Parfois ils sont directement intégrés à la BDD, par exemple le Database Profiler de MongoDB ou l’option slow query log de MySQL.
Que faire si les requêtes externes sont trop lentes ?
L’envoi de requêtes vers un autre serveur, une API par exemple, durant la création d’une page devrait déclencher une grosse alarme rouge. Peu de choses peuvent pénaliser autant les performances d’un backend. Voici mes conseils :
- réduisez leur nombre en urgence (le cache interne est plus que jamais votre ami).
- s’il y en a plusieurs, tentez de les paralléliser.
- vérifiez que le serveur appelé n’est pas trop lent et qu’il n’est pas hébergé sur un autre continent.
- s’il s’agit d’une requête en écriture, envoyez-la vers une solution de file d’attente comme RabbitMQ, puis construisez une mini appli qui enverra les requêtes de façon asynchrone.
Que faire si c’est le code qui est trop lent ?
La plupart du temps, ceci est dû à un framework trop lourd par défaut et vous ne pouvez pas y faire grand-chose. Voici tout de même quelques tuyaux :
- Le profiler pointera du doigt les fonctions les plus lentes, tentez de les réécrire. Si vous ne comprenez pas quelle partie de la fonction est trop lente, scindez-la.
- Si vous repérez une boucle trop lente, cherchez à la simplifier en retirant par exemple certains bouts de code.
- L’écriture de logs peut s’avérer lente lorsqu’elle est utilisée de façon intense. Tentez de remplacer votre logger par une solution plus performante.
- Si votre backend est en PHP, vérifiez sur quelle version il tourne. Les mises à jour récentes du langage apportent d’énormes gains de performance.
Si tout le reste a échoué, passons au hardware !
Premier point, votre serveur doit être géographiquement proche, de la plus grosse partie de votre audience. Même si vous ajoutez un CDN derrière, la distance entre le CDN et le serveur pénalisera les ressources non disponibles en cache. Maintenant, parlons puissance.
Si votre site est hébergé sur un serveur mutualisé, je ne suis vraiment pas surpris qu’il soit lent. Et vous n’avez aucun moyen de savoir pourquoi, c’est une boîte noire. Cela fait partie de la stratégie de l’hébergeur, qui cherche à vous vendre une offre plus chère, mais qui s’avérera être elle aussi… une boîte noire.
Vous l’aurez compris, je ne suis pas fan de la plupart des entreprises qui font de l’hébergement mutualisé. Si j’étais vous, je passerais sur un serveur dédié que je maintiendrais moi-même, mais vous n’êtes peut-être pas bilingue en ligne de commande Linux.
Mon conseil serait alors de choisir un hébergeur qui se soucie vraiment de la performance :
- pour un site WordPress ou WooCommerce, je recommanderais Kinsta et Pressidium, chers (30$ et 42$ respectivement), mais très très rapides avec service premium.
- pour les autres technos basées sur PHP telles Magento, Laravel, Drupal, Prestashop ou Joomla, mes recherches m’ont conduit vers Cloudways.
Si vous possédez un serveur virtuel ou dédié, c’est différent, vous êtes en mesure de détecter le point de ralentissement. Commencez par vérifier le type de disque dur de la machine. Les disques SSD sont 3X plus rapides que les HDD et leur prix a beaucoup baissé ces derniers temps, donc le choix est vite fait.
Ensuite, vérifiez l’utilisation du processeur et de la mémoire grâce à un outil gratuit comme htop. Si les cœurs de votre processeur atteignent souvent 100%, ce n’est pas bon signe. Essayez de choisir une machine avec plus de cœurs ou bien des cœurs plus puissants. Si c’est la mémoire qui est à la peine, ajoutez de la RAM, c’est aussi simple que cela.
Serveur virtuel ou serveur dédié ? Personnellement, je préfère les serveurs dédiés. Ils sont plus rapides et ne subissent pas le « noisy neighbor effect », lorsqu’une application hébergée sur la même machine physique consomme tellement de ressources qu’elle ralentit la vôtre. La tranquillité a un prix, les serveurs dédiés coûtent près de deux fois plus cher que les virtuels.
Si vous cherchez un nouvel hébergeur pour votre serveur, les meilleurs rapports qualité/prix que je connaisse pour des serveurs dédiés – avec SSD bien sûr – sont :
- Scaleway (ex Dedibox) : les serveurs les moins chers sont à partir de 12€ par mois, mais ils sont faiblards. Pour un petit site vous pouvez choisir l’offre à 35€, sinon orientez-vous vers la gamme pro.
- OVH : prix et qualité comparables à la gamme pro de Scaleway, localisations disponible dans le monde entier.
Les serveurs virtuels ont un avantage intéressant : ils sont « scalables ». Vous pouvez facilement ajouter ou retirer de la puissance selon vos besoins. Personnellement j’ai eu une mauvaise expérience avec un serveur virtuel trop lent et pourtant cher. J’ai eu de bons échos à propos de DigitalOcean (en anglais), sinon les offres d’OVHCloud semblent intéressantes.
Une autre stratégie, plutôt que de choisir un serveur très puissant, consiste à augmenter le nombre de serveurs. Il n’y a pas une seule bonne façon de le faire, tout dépend de votre architecture. Vous pouvez avoir plusieurs serveurs full-stack avec du load balancing, mais vous pouvez aussi séparer la base de données du reste, ou bien le frontend et le backend… Contactez-moi si vous avez besoin d’aide.
Que faire en cas de pics de trafic qui ralentissent votre site ?
Il reste un sujet que nous n’avons pas abordé. Votre site subit des ralentissements lors des pics de trafic, malgré l’utilisation d’un CDN. Je prévois de traiter ce sujet dans un futur article, mais voici quelques pistes pour régler le problème en attendant :
- Activez un CDN.
- Vérifiez et revérifiez que toutes les requêtes réalisées par le navigateur vers vos machines sont correctement mises en cache par le CDN. Aidez-vous par exemple d’un outil approprié pour analyser les logs de votre serveur et détecter les requêtes les plus fréquentes.
- Réparez les erreurs 404 (et autres 4** ou 5**). Elles traversent le CDN et atteignent le serveur.
- Utilisez les tests de montée en charge pour simuler l’arrivée massive d’utilisateurs. Faites-le sur un serveur de test, de préférence, ou bien la nuit. Je peux aider à mettre en œuvre ce type de tests si besoin.
Note: cet article contient des liens d’affiliation. Je perçois une petite commission si un achat est réalisé via ces liens.
Super article j’ai beaucoup aimé
Merci, j’approuve avec plaisir ce tout premier commentaire sur le blog 🙂
J’ai une question quand tu dit « jamais avoir un Time to First Byte (mesuré avec WebPageTest) supérieur à 600 millisecondes » pour quel connection : 3G Slow , Fast 3G ou LTE et une deuxieme question pour Mobile ou WEB ?
Tu as raison, j’ai précisé dans l’article la vitesse de connexion pour le test. Je recommande Cable, sinon le temps nécessaire à la connexion au serveur devient plus grande que le temps de réponse du serveur lui-même 🙂
Après, que ce soit depuis un mobile ou un desktop, le temps de réponse du serveur sera le même, sauf s’il y a une redirection vers un site mobile par exemple.