Deux appels strictement identiques à la même fonction de génération de sitemap, dans le cadre d’une seule et même exécution PHP : c’est ce qu’a révélé un profilage de performance sur un script maison chargé de produire l’index général regroupant plusieurs sitemaps segmentés par type de contenu.
Nouveauté d’impact majeur : la découverte du doublon
Le script se décomposait en deux fonctions distinctes : l’une générait l’index listant les sitemaps disponibles, l’autre calculait, pour chacun, le nombre de pages nécessaires. Le problème venait de la fonction d’index, qui appelait la fonction de comptage pour afficher un résumé informatif dans les commentaires XML, puis rappelait indépendamment la même fonction, avec les mêmes paramètres, lors de la génération effective de chaque sitemap segmenté.
function generer_index_sitemaps() {
foreach ( array( 'post', 'page', 'produit' ) as $type ) {
$total_pages = calculer_pages_sitemap( $type ); // premier appel
echo "<!-- {$type} : {$total_pages} pages -->\n";
}
}
function generer_sitemap_segmente( $type ) {
$total_pages = calculer_pages_sitemap( $type ); // second appel identique
for ( $i = 1; $i <= $total_pages; $i++ ) {
// génération du contenu
}
}
Impact secondaire : le coût réel du recalcul
La fonction calculer_pages_sitemap exécutait une requête COUNT sur la table wp_posts, filtrée par type et statut. Sur un site avec plusieurs dizaines de milliers de contenus par type, cette requête restait individuellement rapide, de l’ordre de quelques dizaines de millisecondes, mais son doublement systématique, multiplié par le nombre de types de contenu traités, ajoutait un temps cumulé non négligeable à chaque régénération complète du sitemap, déclenchée à chaque publication via le hook save_post.

Correctif d’impact direct : mémoïsation locale
La solution retenue reste volontairement simple, sans recourir à un cache externe comme Redis ou Memcached, disproportionné pour ce cas précis : une variable statique locale à la fonction, qui conserve le résultat déjà calculé pour un type donné pendant la durée de l’exécution PHP en cours.
function calculer_pages_sitemap( $type ) {
static $cache = array();
if ( isset( $cache[ $type ] ) ) {
return $cache[ $type ];
}
global $wpdb;
$total = (int) $wpdb->get_var( $wpdb->prepare(
"SELECT COUNT(ID) FROM {$wpdb->posts}
WHERE post_type = %s AND post_status = 'publish'",
$type
) );
$cache[ $type ] = (int) ceil( $total / 500 );
return $cache[ $type ];
}
Le mot-clé static à l’intérieur de la fonction PHP conserve la valeur de $cache entre les appels successifs, mais uniquement pour la durée d’une seule exécution du script : à chaque nouvelle requête HTTP ou chaque nouvelle exécution en ligne de commande, le tableau repart vide. C’est exactement le comportement recherché ici, puisque le problème ne portait pas sur la persistance entre deux visites, mais sur la redondance à l’intérieur d’une même exécution.
Nouveauté d’impact secondaire : la trace de débogage
Pour confirmer l’effet du correctif, un compteur temporaire a été ajouté dans la fonction, incrémenté à chaque exécution réelle de la requête SQL, distinct des appels servis depuis la mémoïsation. Ce compteur, affiché en commentaire dans le sitemap généré en environnement de test uniquement, est passé de deux exécutions à une seule par type de contenu, confirmant l’élimination du doublon.
Ce que cette correction n’a pas résolu
- Le temps de génération du sitemap lui-même, pour la boucle de construction du contenu XML, reste inchangé : seule la phase de comptage préalable a été optimisée.
- La mémoïsation locale ne protège pas contre des appels concurrents lors d’exécutions parallèles (plusieurs requêtes HTTP simultanées), chacune conservant sa propre mémoire isolée, ce qui reste le comportement normal et attendu de PHP.
Avant d’ajouter une couche de cache externe à un script, vérifier d’abord si le code n’appelle pas tout simplement deux fois la même fonction avec les mêmes paramètres. C’est un correctif de dix minutes qui règle souvent plus que ce qu’on imaginait au départ.
En résumé
Ce genre de redondance passe facilement inaperçu tant que le volume de données reste modeste, le coût du doublon restant alors négligeable. Il devient visible uniquement à mesure que le catalogue grandit, ce qui en fait un problème de performance à retardement, découvert souvent bien après l’écriture initiale du script. Une mémoïsation locale, simple et sans dépendance externe, suffit dans la grande majorité des cas où le problème se limite à une seule exécution, sans besoin de persistance entre deux requêtes distinctes.