Table des matières de l'article :
La mise en cache peut sembler être la solution miracle à tous les problèmes de performance. Il n'est donc pas surprenant que l'on soit surpris lorsque je dis « Arrêtez d'utiliser la mise en cache » lors de mes présentations ou de mes séances de conseil.
Cependant, comme nous l'avons toujours expliqué partout, une grande partie de notre succès en tant que société d'hébergement Web performante est due aux mécanismes et technologies de cache, allant du cache PHP comme Zend Opcache au cache de page complète de niveau entreprise comme Varnish Cache.
Il n’est donc pas difficile de risquer d’être accusé d’hypocrisie dans certains contextes avec des reproches tels que : « Mais comment se fait-il que vous n’ayez pas dit que la mise en cache améliorait les performances et résolvait les problèmes ? »
Il est donc temps de clarifier ce que j'entends réellement par là, quand et comment utiliser la mise en cache. Et surtout, quand ne pas l'utiliser et quand rechercher des alternatives directement côté développement.
Nous, en tant que société d'hébergement et d'ingénierie système, résolvons les problèmes côté systèmes sans entrer dans le côté développement (si ce n'est pour des requêtes uniques, ou de très petits bugs) sur les sites clients qui se plaignent de problèmes de performances et de vitesse, il est donc normal que Les techniques de mise en cache peuvent cacher les problèmes du côté de l'application, exactement comment la poussière se cache sous le tapis.
Le problème demeure, mais en fait il ne crée pas de problèmes tangibles et le client et ses visiteurs sont heureux de consulter des sites ou de faire des achats sur des sites qui ne se déconnectent pas. Cependant, nous avons toujours aimé une approche adéquate et axée sur les performances de la part des développeurs.
Quand utiliser la mise en cache pleine page ?
Commençons par la plus importante : la mise en cache de page complète. Cette technique consiste à stocker temporairement une version pré-générée d'une page afin de servir exactement le même code (HTML) aux visiteurs pendant une période limitée . Voici comment fonctionne la mise en cache de page complète :
- Le visiteur A visite abc.com/page. Cette page n'est pas mise en cache, atteint PHP et est générée à partir de la base de données. Avant d'être servi au visiteur A, il est également mis en cache pleine page avec une expiration de 10 minutes.
- Le visiteur B visite abc.com/page 2 minutes après le visiteur A et est alors servi avec la même page, mais cette fois directement depuis le cache. Les pages servies aux visiteurs A et B sont identiques.
- Le visiteur C visite abc.com/page 15 minutes après le visiteur A et parce que la version en cache de la page a expiré, la requête atteint à nouveau PHP et la page est régénérée tout comme le visiteur A.
Étant donné que tous ceux qui visitent cette page dans le laps de temps où une page en cache valide existe, la page peut être livrée très rapidement.
Pratiquement aucune ressource n'est utilisée pour fournir une page mise en cache. La mise en cache de la page entière peut donc améliorer les performances et, plus important encore, l'évolutivité. Cela peut sembler très intéressant, mais la mise en cache pleine page présente également de gros inconvénients.
- Si vous souhaitez fournir un contenu dynamique, personnalisé ou autrement différent à différents utilisateurs, cela doit être adressé avec javascript (ajax) qui est exécuté après que le document HTML a été livré au visiteur. Cela peut fonctionner correctement, mais cela nécessite une autre demande supplémentaire au serveur. Si vous utilisez la mise en cache pour éviter d'écrire du code rapide, vous continuerez à rencontrer des problèmes de performances avec vos requêtes ajax dynamiques.
- Ce n'est pas parce que quelque chose fonctionne rapidement pour vous qu'il est rapide pour tout le monde. Les sites Web n'ont pas un seul point d'entrée et les visiteurs accèdent à votre site via une variété de pages. Cela est particulièrement vrai pour WooCommerce, où les visiteurs utilisent Google et parcourent les pages de produits. Ou, si vous effectuez des achats Google sur le catalogue complet avec des liens directement vers les pages de produits. Pour résoudre ce problème, certaines personnes essaient même de le résoudre en "leurrant" le cache de la page entière en utilisant des araignées pour indexer l'ensemble du site afin de s'assurer que chaque page est mise en cache à l'avance. En pratique, cela ne fonctionne pas bien. Il est vulnérable, difficile à installer et à configurer correctement, difficile à entretenir et chronophage, et totalement inutile.
- Vous perdez le contrôle des performances réelles de votre site Web et du fonctionnement du code (ou ne fonctionne pas comme il le devrait). Si vous utilisez la mise en cache pleine page, vous perdez le sens du temps de réponse réel de votre site et de la qualité de votre code. L'expérience montre qu'un manque de concentration sur les performances réelles est la principale raison pour laquelle les sites plantent des jours comme le Black Friday ou lors du déploiement de grandes campagnes.
Qu'en est-il des plugins de mise en cache comme W3 Total Cache ?
Les plugins WordPress comme W3 Total Cache fonctionnent comme toutes les autres pages de cache. Ils stockent une version pré-générée d'une page dans le système de fichiers ou la mémoire et l'offrent aux utilisateurs jusqu'à expiration. W3 Total Cache est utilisé par 1 million de sites Web, mais cela ne signifie pas que c'est une bonne idée. Surtout si vous utilisez un hébergement rapide.
W3 Total Cache est un plugin très volumineux, et pour la plupart des sites, il ajoute simplement beaucoup de code inutile au site Web. Plus il y a de code, plus les choses peuvent mal tourner. Si vous deviez vraiment mettre en cache toute la page, cela ne devrait pas être fait dans la partie PHP de votre application car PHP est lent. La mise en cache de la page complète doit être effectuée aussi près que possible de l'utilisateur sur le serveur Web (NGINX dans notre cas).
W3 Total Cache consiste à charger des pages en moins de 2 secondes en affichant un thème comme TwentySixteen. Pour clarifier, un test similaire sur nos serveurs sera livré en environ 150 millisecondes sans l'utilisation de la mise en cache, pas de secondes.
Alors, quand devriez-vous utiliser la mise en cache pleine page et pourquoi ?
La mise en cache de pages complètes a été créée pour permettre aux sites web à fort trafic de mieux gérer les pics de fréquentation. Elle a été inventée à une époque où l'on utilisait principalement le web pour lire des articles d'actualité. Générer un contenu unique pour chaque visiteur n'est pas pertinent pour les journaux, car leurs pages sont majoritairement statiques et rarement mises à jour. Dans ce cas, la mise en cache de pages complètes est parfaitement adaptée, mais uniquement pour les sites qui ne nécessitent ni connexion utilisateur ni contenu personnalisé ; or, les sites web actuels s'apparentent davantage à des applications.
Les sites web modernes sont plus complexes, dynamiques et de plus en plus personnalisés. Le code lui-même est de plus en plus complexe, et l'ajout de mécanismes encore plus complexes (comme les techniques de mise en cache) à un code déjà complexe n'est pas toujours judicieux. En pratique, cela ajoute une couche technologique supplémentaire qui introduit de nouveaux points de défaillance uniques, nécessitant une maintenance, des mises à jour et des opérations dédiées. Les bugs seront plus difficiles à corriger et le développement global plus complexe (et plus coûteux). Si vous basez vos performances sur la mise en cache de pages entières, je peux vous garantir que la solution s'effondrera si la mise en cache cesse de fonctionner.
La réponse à la question est donc d'écrire du code et des requêtes de bonne qualité et de garder à l'esprit que la solution doit être évolutive. Il est acceptable d'utiliser la mise en cache d'une page complète pour gérer les pics de trafic soudains, tout comme les journaux l'ont fait et le font toujours.
Vous devriez pouvoir désactiver la mise en cache d'une page entière un jour normal, avec un trafic normal, sans vous inquiéter. Et si vous le faites correctement, vous devriez pouvoir désactiver la mise en cache d'une page entière même les jours de pointe, sans planter votre site Web.
Sur le serveur géré, la plupart des magasins fonctionnent sans mise en cache de la page complète, même les jours de fort trafic comme le Black Friday.
WordPress Object Cache : Vous l'utilisez sans le savoir
Beaucoup de gens ignorent que le cache d'objets WordPress est utilisé sur presque tous les sites WordPress. Et oui, le cache d'objets est efficace même si vous n'utilisez pas de cache d'objets externe, comme MemCached ou REDIS.
Comment fonctionne le cache d'objets WordPress ?
- Vous faites une demande d'utilisation des valeurs postmeta c'est à dire
get_post_meta() - WordPress exécute la requête et obtient le résultat de la base de données et stocke automatiquement le résultat dans le cache d'objets (mémoire, RAM)
- Vous obtenez le résultat et l'utilisez quelque part dans votre code
- Plus tard dans votre code, faites-en un autre
get_post_meta()demander les mêmes données - WordPress l'a déjà dans le cache d'objets et le renvoie directement sans interroger à nouveau la base de données
- La page est livrée au visiteur et le cache d'objets est vidé (mémoire libérée)
Toutes les fonctions WordPress n'enregistrent pas leurs résultats dans le cache d'objets, mais get_post_meta() ils le font. En effet, la table _postmeta de la base de données peut devenir très volumineuse et les requêtes peuvent devenir coûteuses (utiliser beaucoup de ressources de traitement).
En tant que développeur, vous pouvez ajouter vous-même des résultats au cache d'objets , ce qui accélère leur réutilisation ultérieure. Si vous écrivez vos propres requêtes avec, par exemple, WP_Query, vous devrez mettre les résultats en cache vous-même. Il est important de se rappeler, cependant, que comme pour tout système de cache, il ne faut pas s'y fier. Veillez donc à ne pas écrire de code qui suppose que vos résultats se trouvent dans le cache d'objets.
Vous pouvez vérifier les performances de votre cache d'objets et le nombre de requêtes de base de données en installant un plugin comme Query Monitor.
Dans nos tests avec un WooCommerce normal, un taux de réussite normal du cache d'objets se situe entre 95% et 98%.
Comment utiliser le cache d'objets WordPress pour vos requêtes
$ result = wp_cache_get ('some_unique_name'); if (false === $ result) {$ result = $ wpdb-> get_results ($ query); wp_cache_set ('some_unique_name', $ result); } // Faire quelque chose avec $ result ; Cet exemple de code essaie d'abord d'obtenir un $result, puis vérifiez s'il y a vraiment un résultat en $. wp_cache_get()résultats falses'il n'existe pas. S'il n'y a pas de données, nous interrogeons nos données, puis les stockons dans wp_cache_set() afin qu'ils soient disponibles pour de futures demandes.
Qu'en est-il des caches d'objets externes comme MemCached et REDIS ?
Un cache d'objets externe peut fournir ce que l'on appelle plus précisément un « cache d'objets persistant ». Il s'agit d'un cache d'objets qui n'est pas téléchargé entre les pages vues ; par conséquent, il stocke ses données dans différentes pages vues. Idée intelligente, non ? Mais comme d'habitude avec la mise en cache, ce n'est pas si simple.
- Le gain de performances potentiel lié à l'utilisation d'un cache d'objets persistant est limité aux hits qui échouent dans le cache d'objets. En utilisant le taux d'accès au cache non persistant par défaut de 95 % à 98 %, le potentiel d'amélioration des performances se situe entre 2 % et 5 % de la demande. De plus, un cache d'objet externe ajoutera une latence supplémentaire car il s'agit d'une application externe, il ralentira donc de 95 à 98 % ce qui était servi directement dans PHP auparavant. Le gain net de la latence supplémentaire + le gain de performances du cache d'objets externes vont souvent mal pour les magasins de commerce électronique.
- Même si vous utilisez un cache d'objets externe, vous ne pouvez pas faire confiance à l'existence des informations lors de l'écriture du code.
- Si vous dépendez d'un cache d'objets externe pour charger les pages à une vitesse décente, cela signifie que votre code n'est pas valide, que les requêtes de la base de données sont trop lourdes ou qu'elles sont trop nombreuses. Le vrai problème est dans votre code, pas dans la réactivité de la base de données. C'est pourquoi vous ne devriez pas utiliser le patch MemCached ou Redis.
- Si vous utilisez une base de données rapide et optimisée qui utilise correctement les index, vous n'avez pas besoin d'un cache d'objets externe.
Si vous n'avez pas besoin d'un cache d'objets externe, il peut être dangereux d'en utiliser un
Cela vaut vraiment pour toute la technologie que vous incluez dans votre pile Web, dont vous n'avez pas besoin. Si vous l'avez, le risque d'en devenir accro est grand, même si vous n'en avez pas vraiment besoin. Si vous en dépendez, vous augmentez les chances que quelque chose tourne mal. De plus, chaque technologie ajoutée à la pile nécessite une installation, une configuration, une maintenance, des mises à jour de sécurité et introduit un autre point de défaillance unique.
Les transitoires peuvent être bons, mais ils peuvent aussi nuire à votre site
Les transitoires sont utilisés par WordPress et une variété de plugins, et le concept est assez simple. Vous faites une demande et enregistrez le résultat, ou des parties de celui-ci, dans la base de données pour une réutilisation ultérieure. Contrairement au cache d'objets, aucune technologie supplémentaire n'est nécessaire pour rendre cela persistant d'une page à l'autre, car les données sont stockées dans la base de données. Les transitoires peuvent ou non avoir un délai d'expiration - c'est votre choix.
Personnellement, je n'aime pas l'utilisation excessive des transitoires, et il y a de nombreuses raisons à cela
- Les transitoires sont enregistrés dans la table WordPress _options. Cette table est déjà très utilisée et une écriture excessive dans _options peut introduire des problèmes de blocage (mise en file d'attente).
- L'utilisation excessive de transitoires se traduira par une grande table _options. Chaque vue de page individuelle dépend de cette table, et une grande table d'options peut dégrader les performances sur toutes les vues de page.
- Les transitoires qui n'expirent pas seront interrogés à chaque chargement de page (chargement automatique) via wp_load_alloptions(). Cela réduira les performances sur toutes les pages vues.
Cela dit, les données transitoires peuvent optimiser les performances lorsqu'elles sont utilisées correctement. Si vous interrogez des données fréquemment utilisées mais rarement modifiées, il peut être judicieux de stocker le résultat dans des données transitoires. Il est beaucoup plus simple pour WordPress de récupérer la valeur de la clé X dans la table `_options` que d'effectuer des requêtes SELECT sur d'autres tables. Cependant, si vous utilisez des données transitoires, veillez à surveiller la table `_options` pour éviter une croissance excessive et assurez-vous de mettre en place un mécanisme de nettoyage pour les données transitoires inutilisées ou expirées. Enfin, n'utilisez jamais de données transitoires pour des données nécessitant des mises à jour fréquentes, car cela ralentira les performances.
La mise en cache des fragments est bonne lorsqu'elle est utilisée correctement
Le Fragment Cache est un type de mise en cache où l'on stocke un élément, une partie d'une page, ou autre chose dont la génération est coûteuse en termes de ressources et/ou est souvent utilisée. Beaucoup ont choisi d'implémenter la fonctionnalité de Mark Jaquith pour effectuer la mise en cache de fragments dans WordPress.
La mise en cache de fragments consiste à stocker un résultat (sortie HTML) afin qu'il puisse être livré beaucoup plus rapidement par la suite. L'idée est aussi simple que surprenante. Vous pouvez choisir les éléments à mettre en cache et vous n'avez pas besoin de mettre en cache l'intégralité de la sortie, comme la mise en cache d'une page complète.
La façon dont vous procédez dans WordPress équivaut à la mise en cache d'objets, car il n'y a pas de limite aux données que vous pouvez mettre en cache. Par conséquent, les mêmes principes s'appliquent; ne faites jamais confiance à quelque chose qui est mis en cache, assurez-vous de ne pas en dépendre et concentrez-vous sur votre code plutôt que de prendre le raccourci du cache de fragments.
Beaucoup implémentent la mise en cache des fragments basée sur la mémoire. Mais pour que cela prenne effet, un cache d'objets externe est nécessaire pour rendre les éléments disponibles dans les vues de page (voir ci-dessus). Je recommande une utilisation douce de la mise en cache des fragments et du stockage des données dans les transitoires. En pratique, cela vous donnera les mêmes résultats en termes de performances, sans ajouter de technologie supplémentaire à votre pile.
Voici comment enregistrer les transitoires
$ sortie = get_transient ('some_unique_key'); if ($ output === false) {$ output = 'Quelques données'; set_transient ('some_unique_key', $ sortie, 3600); } // Faire quelque chose avec la sortie $ Dans cet exemple de code, nous lisons $output à partir d'un transitoire et testez si la sortie $ existe. Soi get_transient()résultats false , nous générons les données et les stockons dans un transitoire pour une utilisation ultérieure.
Quelle technique de mise en cache dois-je utiliser et quand ?
Il utilise le stockage Full Page Cache pour la mise à l'échelle, c'est pour cela qu'il est fait : il n'est pas fait pour améliorer les performances. Assurez-vous de ne pas devenir accro à cela. Vous devriez pouvoir désactiver la mise en cache de pages entières sans subir de perte de performances significative.
Utilisez le cache d'objets autant que possible, surtout si vous utilisez WooCommerce, mais évitez les caches d'objets externes ; ils engendrent toutes sortes de nouveaux problèmes. Les caches externes détournent votre attention des aspects les plus importants de votre application. Une meilleure solution consiste à opter pour un hébergement plus rapide avec des bases de données performantes comme la nôtre.
Vous devez utiliser des transitoires pour les requêtes fréquentes qui ne changent pas beaucoup. Assurez-vous de définir une date d'expiration appropriée en fonction de la fréquence à laquelle les données doivent être mises à jour.
Assurez-vous également de supprimer les transitoires expirés. Utilisez le cache de fragments dans les transitoires pour les éléments gourmands en ressources et fréquemment utilisés.