Un client se plaignait d’une page produit particulièrement lente, sans qu’aucun plugin de cache ni aucune optimisation de base de données ne parvienne à résoudre le problème. Query Monitor montrait des requêtes SQL individuellement rapides, aucune ne dépassant 20 millisecondes. Le problème se situait donc ailleurs, quelque part dans l’exécution PHP elle-même. C’est le terrain du profiling : là où le débogage classique s’arrête, un profileur montre exactement où le temps d’exécution se concentre.
Étape 1 : choisir l’outil selon le contexte
Trois outils dominent l’écosystème PHP, avec des usages différents. Xdebug, gratuit et déjà présent sur beaucoup d’environnements de développement, convient parfaitement à un diagnostic local, mais son surcoût de performance (souvent un facteur de ralentissement de deux à cinq) le rend impraticable en production. Blackfire et Tideways, payants, sont conçus pour profiler en conditions réelles avec un surcoût de quelques pourcents seulement, ce qui permet de capturer un profil sur le trafic réel plutôt que sur un scénario reconstitué.
Étape 2 : générer un profil avec Xdebug en local
; php.ini de l'environnement local
xdebug.mode=profile
xdebug.output_dir=/tmp/xdebug-profiles
Chaque requête PHP génère un fichier cachegrind.out.* dans le dossier indiqué, lisible avec un outil comme QCacheGrind ou son équivalent en ligne :
qcachegrind /tmp/xdebug-profiles/cachegrind.out.123456
Étape 3 : lire un call graph sans se perdre
Un call graph présente les fonctions appelées sous forme de boîtes reliées, avec deux mesures essentielles à distinguer : le temps propre (le temps passé dans la fonction elle-même, hors appels à d’autres fonctions) et le temps cumulé (le temps propre plus celui de toutes les fonctions appelées depuis celle-ci). Beaucoup de développeurs débutants se laissent piéger par le temps cumulé d’une fonction de haut niveau, qui semble énorme simplement parce qu’elle appelle tout le reste.

La bonne méthode consiste à trier par temps propre décroissant, et à remonter à la fonction qui consomme réellement le plus de temps en elle-même, indépendamment de ce qu’elle appelle.
Étape 4 : profiler en production avec Tideways
Sur ce projet, Xdebug n’était pas envisageable en production. L’installation de l’agent Tideways a permis de capturer un échantillon de requêtes réelles sans ralentir le site de façon perceptible :
sudo apt install tideways-php
sudo systemctl restart php8.1-fpm
Le tableau de bord Tideways a immédiatement mis en évidence une fonction représentant 89 % du temps d’exécution total de la page produit : une fonction de calcul de recommandations « produits similaires », fournie par une extension tierce, qui recalculait la similarité entre le produit courant et l’ensemble du catalogue à chaque affichage, sans aucun cache.
Étape 5 : remonter à la fonction coupable et corriger
Une fois la fonction identifiée précisément (avec son fichier et son numéro de ligne, fournis par le profileur), le correctif a consisté à mettre en cache le résultat du calcul de similarité par produit, invalidé uniquement lors de la modification du catalogue :
function wpm_produits_similaires_caches( $product_id ) {
$key = "similaires_{$product_id}";
$ids = get_transient( $key );
if ( false === $ids ) {
$ids = wpm_calculer_produits_similaires( $product_id );
set_transient( $key, $ids, DAY_IN_SECONDS );
}
return $ids;
}
Checklist avant de lancer une session de profiling
- Reproduire le problème sur un scénario précis, pas une session de navigation aléatoire, pour capturer un profil exploitable.
- Choisir Xdebug uniquement en local, jamais sur un environnement de production accessible aux visiteurs.
- Trier systématiquement par temps propre, pas par temps cumulé, pour identifier la vraie fonction coupable.
- Conserver les profils avant/après correctif, pour documenter le gain réellement obtenu.
Ce que le profiling ne remplace pas
Un profileur montre où le temps passe, pas pourquoi le code a été écrit ainsi. Il reste nécessaire de comprendre la logique métier avant de corriger : dans ce cas, comprendre que le calcul de similarité pouvait raisonnablement se rafraîchir une fois par jour, plutôt qu’à chaque requête, demandait une discussion avec l’équipe produit du client, pas seulement un correctif technique isolé.
Un profil d’exécution ne ment jamais sur où le temps passe, contrairement aux intuitions qu’on se forge en lisant le code sans mesurer.
En résumé
Xdebug pour le diagnostic local ponctuel, Blackfire ou Tideways pour un diagnostic fiable en conditions réelles de production : ces trois outils couvrent la quasi-totalité des besoins de profiling PHP sur un projet WordPress. La compétence à développer n’est pas tant l’installation de l’outil que la lecture rigoureuse du call graph, en distinguant systématiquement temps propre et temps cumulé.