vendredi 25 septembre 2026

À propos

Contact

Performance

Cache de fragments dans un thème : mettre en cache des morceaux de page

Menus complexes, widgets lourds, blocs de template coûteux : comment les mettre en cache via le cache d'objets, avec une stratégie d'invalidation propre.

Par Clément Hadrot • 23 juin 2021 • 4 min de lecture • Aucun commentaire
Cache de fragments dans un thème : mettre en cache des morceaux de page

Le cache de page classique met en cache la réponse HTML complète : rapide et simple, mais tout ou rien. Il devient inadapté dès qu’une page contient une zone réellement dynamique (un compte utilisateur, un panier) à côté de zones lourdes mais identiques pour tous les visiteurs, comme un mega-menu ou un widget de derniers articles avec des requêtes complexes. C’est là qu’intervient le cache de fragments : mettre en cache des morceaux de page indépendamment, via le cache d’objets, tout en laissant le reste de la page se générer normalement.

Arborescence type d’une architecture de cache de fragments

theme/
├── inc/
│   ├── cache/
│   │   ├── class-fragment-cache.php
│   │   └── invalidation.php
├── template-parts/
│   ├── mega-menu.php
│   ├── widget-articles-recents.php
│   └── footer-liens.php
└── functions.php

L’idée directrice : chaque composant coûteux à générer dispose de sa propre classe ou fonction de mise en cache, avec une clé et une durée de vie qui lui sont propres, plutôt qu’une seule règle appliquée uniformément à toute la page.

Une classe de cache de fragments réutilisable

class WPM_Fragment_Cache {
    public static function get( $key, callable $generator, $ttl = HOUR_IN_SECONDS ) {
        $cached = wp_cache_get( $key, 'wpm_fragments' );

        if ( false !== $cached ) {
            return $cached;
        }

        $output = $generator();
        wp_cache_set( $key, $output, 'wpm_fragments', $ttl );

        return $output;
    }
}

Usage dans un template part, pour le mega-menu qui recalculait auparavant l’arborescence complète à chaque affichage :

echo WPM_Fragment_Cache::get(
    'mega_menu_html',
    function () {
        ob_start();
        wpm_render_mega_menu();
        return ob_get_clean();
    },
    HOUR_IN_SECONDS
);

Sur ce projet, la génération du mega-menu, qui interrogeait sept niveaux de taxonomie à chaque affichage, prenait 340 millisecondes. Une fois mis en cache, la lecture depuis le cache d’objets Redis tombe à environ 4 millisecondes.

L'essentiel à retenir : Le cache de fragments cible un composant, pas la page entière ; Sans invalidation propre, un cache de fragments devient une source de bugs ; Chaque fragment mérite sa propre durée de vie

La stratégie d’invalidation, le vrai sujet

Un cache de fragments mal invalidé affiche du contenu obsolète, souvent de façon discrète et difficile à détecter en recette. Chaque fragment doit être invalidé par les événements qui le concernent réellement, pas par un délai arbitraire seul :

function wpm_invalidate_menu_cache( $menu_id ) {
    wp_cache_delete( 'mega_menu_html', 'wpm_fragments' );
}
add_action( 'wp_update_nav_menu', 'wpm_invalidate_menu_cache' );

function wpm_invalidate_recent_posts_cache( $post_id ) {
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    wp_cache_delete( 'widget_articles_recents', 'wpm_fragments' );
}
add_action( 'save_post', 'wpm_invalidate_recent_posts_cache' );

La durée de vie (TTL) reste utile comme filet de sécurité, au cas où un événement d’invalidation serait oublié, mais elle ne doit jamais être la seule ligne de défense contre le contenu obsolète.

Quels composants sont de bons candidats

  • Les menus complexes générés à partir de taxonomies ou de requêtes personnalisées.
  • Les widgets de barre latérale qui exécutent une requête coûteuse (articles populaires calculés dynamiquement, par exemple).
  • Les blocs de pied de page identiques sur tout le site mais reconstruits à chaque chargement.
  • Les zones de recommandation de contenu basées sur des calculs de similarité.

Ce que le cache de fragments ne couvre pas

Les blocs dynamiques Gutenberg (comme les blocs de requête ou les blocs interactifs de l’Interactivity API) suivent une logique de rendu différente, souvent liée au contexte de la requête individuelle, et ne se prêtent pas toujours bien à ce mécanisme sans adaptation spécifique.

Un cache de fragments bien conçu se voit à un détail : il devient invisible pour l’équipe éditoriale, qui ne remarque jamais de contenu en retard.

En résumé

Le cache de fragments comble un vide entre le cache de page, trop grossier pour les pages partiellement dynamiques, et l’absence totale de cache. Sa complexité réside presque entièrement dans l’invalidation : bien pensée événement par événement, elle transforme des composants coûteux en quasi-gratuits sans jamais afficher de contenu périmé.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi