Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Cache de fragments contre cache d’objet pour une requête GraphQL coûteuse

Deux stratégies de mise en cache existent pour une résolution WPGraphQL imbriquée coûteuse, avec des coûts d'invalidation très différents selon celle retenue.

Par WordPress Développement • 13 décembre 2021 • 4 min de lecture • Aucun commentaire
Cache de fragments contre cache d'objet pour une requête GraphQL coûteuse

Une requête GraphQL imbriquée sur trois niveaux — un article, ses commentaires, l’auteur de chaque commentaire — peut déclencher plusieurs dizaines d’appels de résolveurs individuels côté WPGraphQL, chacun capable de lancer sa propre requête SQL si aucune mise en cache n’intervient. Sur un contenu qui change rarement, refaire ce travail à chaque appel du front headless représente un gaspillage évident ; reste à choisir où placer le cache.

Le cache de fragments

Cette approche mémorise la réponse complète d’une requête GraphQL donnée, associée à sa signature exacte — la requête elle-même plus ses variables. À la prochaine requête strictement identique, WPGraphQL renvoie directement le résultat stocké, sans exécuter le moindre résolveur. C’est la logique derrière l’extension WPGraphQL Smart Cache, qui construit ce cache par requête et l’associe à des étiquettes (les types de contenu et identifiants impliqués dans la réponse) pour permettre une invalidation ciblée lors d’une publication ou d’une modification de contenu.

L’avantage principal tient à sa simplicité conceptuelle : une requête entièrement en cache ne coûte quasiment rien à servir, quelle que soit sa complexité interne. L’inconvénient tient à sa granularité : deux requêtes qui diffèrent d’une seule variable, ou d’un seul champ demandé, constituent deux entrées de cache totalement distinctes, sans aucun partage entre elles, même si elles recouvrent en grande partie les mêmes données.

Le cache d’objet

L'essentiel à retenir : Le cache de fragments mémorise une réponse GraphQL complète par requête ; Le cache d'objet mémorise les résultats intermédiaires des résolveurs ; L'invalidation du cache de fragments est plus grossière mais plus simple

Cette seconde approche descend d’un niveau : plutôt que de mémoriser la réponse complète, elle mémorise le résultat de chaque résolveur individuel, généralement via l’objet de cache natif de WordPress (wp_cache_get() et wp_cache_set(), potentiellement adossés à Redis ou Memcached en production). Quand deux requêtes GraphQL différentes demandent toutes les deux l’auteur du même article, le résolveur correspondant n’est exécuté qu’une seule fois ; la seconde requête profite du résultat déjà mémorisé, même si le reste de sa structure diffère totalement de la première.

Cette granularité plus fine permet un partage de cache entre des requêtes qui ne se ressemblent pas en surface, mais interrogent en partie les mêmes données. Elle a un coût : chaque résolveur doit explicitement gérer son propre cache, ce qui alourdit le code de chaque extension de champ personnalisé, et l’invalidation doit être pensée résolveur par résolveur plutôt que de façon globale.

Comparatif

CritèreCache de fragmentsCache d’objet
GranularitéToute la réponse GraphQLChaque résolveur individuellement
Partage entre requêtes différentesAucunÉlevé sur les données communes
Complexité d’implémentationFaible (extension dédiée)Élevée (code par résolveur)
InvalidationPar étiquette de contenu, assez grossièreFine mais à maintenir résolveur par résolveur
Effet sur une requête totalement nouvelleAucun gain (jamais vue)Gain partiel si les données sous-jacentes sont déjà en cache

Un exemple de coût d’invalidation

// Cache de fragments : l'extension écoute la publication d'un contenu
// et purge elle-même toutes les réponses associées à son identifiant,
// sans intervention manuelle à écrire côté projet.

// Cache d'objet : invalidation ciblée d'une seule entrée
wp_cache_delete( 'auteur_128', 'wpgraphql_resolveurs' );

Sur un site où les publications restent peu fréquentes mais où le trafic en lecture est important, le cache de fragments suffit largement : la fraîcheur du contenu importe moins que la simplicité de l’invalidation. Sur un site où le contenu évolue en continu, avec des champs partagés entre de nombreux types de requêtes différentes, le cache d’objet devient plus rentable malgré son coût d’implémentation, car il évite de reconstruire des données identiques à chaque nouvelle forme de requête.

Notre verdict

Aucune des deux approches ne domine universellement l’autre. Le cache de fragments reste le point de départ le plus rentable pour la majorité des projets, avec un effort d’implémentation minimal et un gain immédiat sur les requêtes répétées à l’identique. Le cache d’objet ne se justifie que lorsque le nombre de formes de requêtes distinctes devient trop élevé pour que le cache de fragments continue d’offrir un taux de succès satisfaisant, ce qui reste, en pratique, un cas plus rare que ce que sa popularité théorique laisserait penser.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi