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

Performance

hrtime() pour isoler le coût de chargement de chaque extension au démarrage

Quarante extensions actives, un temps de démarrage qui traîne. Une méthode simple avec hrtime() isole, une par une, ce que chacune ajoute réellement.

Par Clément Hadrot • 6 septembre 2026 • 4 min de lecture • Aucun commentaire
hrtime() pour isoler le coût de chargement de chaque extension au démarrage

hrtime( true ) renvoie un nombre de nanosecondes écoulées depuis un point de référence arbitraire, sans dérive liée à l’horloge système contrairement à microtime(). Placée à des points précis du cycle de démarrage de WordPress, cette fonction a permis de répondre à une question que peu d’outils de profilage grand public traitent directement : parmi quarante extensions actives sur un site de recrutement spécialisé, laquelle coûte quoi, exactement, au tout premier instant du chargement ?

Le temps de démarrage global de WordPress, avant même l’exécution de la moindre requête à la base de données propre au thème, dépassait 400 millisecondes sur ce site, une valeur jugée excessive pour un simple chargement des extensions et du cœur. Plutôt que de désactiver les extensions une par une pour observer l’effet global — une méthode lente et imprécise sur un parc de quarante modules — la mesure directe du temps de chargement de chacune a été préférée.

La méthode : instrumenter le hook plugins_loaded

WordPress charge chaque fichier principal d’extension avant de déclencher l’action plugins_loaded. Pour mesurer individuellement le coût de chaque extension, un petit script placé dans un fichier mu-plugin — chargé avant toutes les autres extensions — a intercepté la liste des fichiers d’extensions actives et mesuré le temps d’inclusion de chacun séparément :

$actives = get_option( 'active_plugins', array() );
$mesures = array();

foreach ( $actives as $fichier ) {
    $chemin = WP_PLUGIN_DIR . '/' . $fichier;
    if ( ! file_exists( $chemin ) ) {
        continue;
    }
    $debut = hrtime( true );
    include_once $chemin;
    $duree = ( hrtime( true ) - $debut ) / 1e6; // millisecondes
    $mesures[ $fichier ] = $duree;
}

// Écriture dans un fichier de log dédié, hors requête HTTP normale
file_put_contents(
    WP_CONTENT_DIR . '/wpm-audit-demarrage.log',
    print_r( $mesures, true )
);

Cette approche contourne le mécanisme normal de chargement des extensions par WordPress, ce qui l’a réservée à un environnement de recette isolé, jamais exécutée en production, où le chargement standard des extensions reste inchangé.

Ce que la mesure a révélé

L'essentiel à retenir : Le temps de démarrage global ne dit pas quelle extension coûte quoi ; hrtime() a permis de mesurer chaque extension individuellement ; Trois extensions représentaient à elles seules plus de la moitié du coût total

Sur les quarante extensions actives, trente-sept se chargeaient chacune en moins de 4 millisecondes, un coût négligeable pris individuellement. Trois extensions concentraient à elles seules 340 des 410 millisecondes de temps de démarrage total :

ExtensionTemps de chargement mesuré
Extension de recherche avancée par facettes165 ms
Extension de gestion des candidatures110 ms
Extension d’export de données vers un tableur65 ms

Pourquoi ces trois extensions coûtaient autant

L’inspection du code de l’extension de recherche par facettes a révélé qu’elle chargeait, dès son fichier principal, l’intégralité d’une bibliothèque tierce de traitement de texte, y compris ses dictionnaires de synonymes multilingues, alors que le site n’utilisait qu’une seule langue. L’extension de gestion des candidatures, elle, exécutait une requête de vérification de licence à chaque chargement de page, avant même que plugins_loaded ne soit déclenché, via un appel réseau bloquant placé directement dans son fichier principal.

Les correctifs apportés

  • L’éditeur de l’extension de recherche par facettes a confirmé qu’un paramètre de configuration permettait de désactiver le chargement des dictionnaires non utilisés, réduisant son coût à 40 millisecondes.
  • La vérification de licence de l’extension de candidatures a été mise en cache via un transient d’une heure, côté extension elle-même après échange avec son éditeur, ramenant son coût à 8 millisecondes.
  • L’extension d’export vers un tableur, peu utilisée au quotidien, a été remplacée par une extension équivalente chargée uniquement à la demande, via admin_enqueue_scripts, plutôt qu’au démarrage systématique de chaque page.

Les limites de cette méthode de mesure

Cette technique mesure le coût d’inclusion du fichier principal de chaque extension, mais pas nécessairement l’ensemble de son impact : une extension peut se charger rapidement puis ajouter un traitement coûteux plus tard dans le cycle de requête, via un hook déclenché seulement sur certaines pages. Elle constitue un point de départ, pas un diagnostic complet à elle seule.

Le temps de démarrage global ne raconte qu’une moyenne ; isoler chaque extension révèle presque toujours qu’une poignée d’entre elles concentre l’essentiel du coût, le reste n’étant que du bruit statistique.

En résumé

Sur quarante extensions actives, trois seulement représentaient plus de 80 % du temps de démarrage mesuré. La méthode par hrtime(), appliquée directement sur le chargement de chaque fichier principal, a permis d’isoler précisément ces trois coupables sans avoir à désactiver et réactiver méthodiquement chaque extension une par une.

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