Comment mettre en cache une page qui affiche « Bonjour Julie, vous avez terminé 4 modules sur 12 » sans la servir telle quelle à Marc, qui en est à 9 modules sur 12 ? C’est la question posée par une plateforme de formation à distance dont le tableau de bord apprenant, construit avec Elementor et Elementor Pro Forms pour les évaluations, ne pouvait pas être mis en cache de façon classique, page entière.
Avec 30 000 comptes apprenants actifs et des pics de connexion entre 18 h et 21 h en semaine, le serveur PHP-FPM saturait régulièrement, non pas à cause du contenu des cours eux-mêmes (servi en pages statiques classiques), mais à cause des pages de tableau de bord, systématiquement exclues du cache par les plugins habituels dès qu’un cookie de session était détecté.
Cartographier ce qui est vraiment personnalisé
Le premier travail n’a pas été technique mais fonctionnel : lister, gabarit par gabarit construit dans le Theme Builder Elementor, ce qui changeait réellement selon l’utilisateur connecté. Résultat inattendu : sur la page de tableau de bord, seuls trois blocs affichaient une donnée propre à l’apprenant (progression, prochaine échéance, messages non lus). Le reste de la mise en page, la navigation, le pied de page, les widgets de recommandation de parcours, étaient identiques pour tous les apprenants d’un même rôle.
Cette distinction a changé toute la stratégie : au lieu d’exclure la page entière du cache, il devenait possible de mettre en cache la coquille de la page et de charger les trois blocs personnalisés séparément.
Trois niveaux de cache superposés
La solution retenue combine trois mécanismes complémentaires plutôt qu’un seul plugin de cache généraliste.

Niveau 1 : cache de page par rôle
La coquille de la page (structure Elementor, styles, navigation) est mise en cache une fois par rôle utilisateur (apprenant, tuteur, administrateur pédagogique) plutôt qu’une fois par utilisateur, grâce à une clé de cache construite sur wp_get_current_user()->roles au lieu de l’identifiant individuel.
Niveau 2 : fragments dynamiques en AJAX
Les trois blocs réellement personnels sont extraits de la mise en page Elementor et transformés en appels AJAX indépendants, déclenchés après le chargement de la page, avec leur propre cache objet de courte durée (60 secondes) côté serveur via wp_cache_set().
Niveau 3 : purge ciblée par transition
Chaque validation de module déclenche une purge du cache objet limitée à l’utilisateur concerné, sans jamais invalider le cache de page partagé par rôle.
Les chiffres mesurés sur trois semaines
| Indicateur | Avant | Après |
|---|---|---|
| Requêtes serveur / minute (pic 19 h) | 1 240 | 396 |
| Temps de réponse moyen tableau de bord | 1,9 s | 0,6 s |
| Charge CPU moyenne serveur (pic) | 91 % | 34 % |
La réduction de 68 % des requêtes serveur aux heures de pointe a permis de repousser d’un an l’investissement prévu dans un serveur supplémentaire, un argument qui a compté davantage auprès de la direction que les gains de vitesse ressentis.
Ce qui reste hors périmètre
Cette stratégie de cache ne touche pas au moteur de cours lui-même (SCORM, suivi xAPI ou équivalent), ni à la gestion des paiements et des abonnements, deux briques gérées par des systèmes tiers connectés à la plateforme. Le cache par rôle ne résout que la couche d’affichage Elementor du tableau de bord.
- Cache de coquille par rôle, pas par utilisateur
- Fragments personnels chargés en AJAX avec cache objet court
- Purge ciblée sur événement, jamais de purge globale
Un cache par rôle ne remplace pas un cache par utilisateur : il fonctionne parce que la personnalisation réelle tient en trois blocs, pas en une page entière.
Ce qu’il reste à surveiller dans la durée
Une architecture de cache par rôle introduit un risque propre : si un nouveau widget personnalisé est ajouté au tableau de bord sans passer par la même analyse (coquille partagée versus fragment individuel), il finit presque toujours par afficher une donnée personnelle depuis le cache de coquille partagé par rôle, un bug silencieux et potentiellement gênant en matière de confidentialité entre apprenants. Une check-list courte a donc été ajoutée à la procédure de recette avant toute mise en production d’un nouveau bloc du tableau de bord.
Notre verdict
Sur un site où l’essentiel de la mise en page Elementor est partagé entre utilisateurs d’un même rôle, isoler les fragments réellement dynamiques rapporte plus qu’une exclusion totale du cache. La contrepartie est un travail d’audit plus long en amont, et une architecture AJAX à maintenir dans la durée, moins transparente qu’un plugin de cache clé en main, et qui exige une vigilance constante à chaque évolution du tableau de bord.