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

Performance

Pourquoi le hook init n’est pas toujours le bon endroit pour économiser du temps

La documentation du cœur WordPress précise ce que garantit chaque hook de chargement. Comprendre cette séquence évite d'initialiser trop tôt un traitement coûteux.

Par Clément Hadrot • 1 septembre 2022 • 4 min de lecture • Aucun commentaire
Pourquoi le hook init n'est pas toujours le bon endroit pour économiser du temps

« Fires after WordPress has finished loading but before any headers are sent. » Cette phrase, tirée de la documentation officielle du hook init, décrit précisément ce que ce point d’accroche garantit, et surtout ce qu’il ne garantit pas : que toutes les extensions actives aient elles-mêmes terminé leur propre initialisation.

Un plugin de cache de fragments, développé pour accélérer un site à fort trafic, enregistrait son mécanisme de lecture du cache sur init, en tentant de vérifier si un autre plugin de personnalisation avait déjà enregistré ses propres filtres de contenu. Le problème : selon l’ordre de chargement des extensions, ce second plugin n’avait parfois pas encore eu l’occasion de s’enregistrer au moment où init se déclenchait pour le premier.

Ce que le hook init garantit réellement

init se déclenche après que WordPress a chargé le cœur, activé les plugins et le thème, et reconnu la requête entrante, mais avant l’envoi des en-têtes HTTP. Il reste néanmoins possible que certains plugins retardent volontairement une partie de leur propre initialisation à un hook ultérieur, pour des raisons qui leur sont propres, ce qui rend risqué tout code qui suppose que « tout » est prêt dès init.

Les hooks suivants et ce qu’ils apportent

  • wp_loaded se déclenche une fois que WordPress et tous les plugins actifs ont terminé de charger, un point plus fiable pour vérifier la présence de fonctionnalités enregistrées par d’autres extensions.
  • parse_request intervient après que WordPress a déterminé quelle requête est en cours de traitement, utile pour des décisions qui dépendent du type de page demandée.
  • template_redirect se déclenche juste avant le choix du template à charger, le dernier moment raisonnable pour intervenir sur le flux d’affichage avant le rendu proprement dit.
L'essentiel à retenir : init se déclenche avant que toutes les extensions ne soient chargées ; Un traitement dépendant d'une autre extension doit attendre un hook plus tardif ; wp_loaded garantit que tous les plugins ont fini leur propre initialisation

Ce que le mauvais positionnement coûtait ici

Le plugin de cache de fragments, faute de trouver les filtres attendus lors de son passage sur init, retombait systématiquement sur un chemin de secours plus coûteux, recalculant certains fragments qui auraient normalement dû être servis directement depuis le cache. Ce comportement dégradé passait inaperçu en apparence, puisque le site continuait de fonctionner correctement, seulement plus lentement qu’attendu sur certaines pages.

Le correctif appliqué

add_action('wp_loaded', function () {
    if (function_exists('personnalisation_filtres_actifs')) {
        add_filter('cache_fragment_contexte', 'lire_contexte_personnalisation');
    }
});

Déplacer l’enregistrement du filtre de init vers wp_loaded a suffi à garantir que la fonction de l’autre plugin, quel que soit son ordre de chargement relatif, soit systématiquement disponible au moment de la vérification.

Une confusion fréquente à corriger

Beaucoup de développeurs choisissent init par habitude, parce que c’est le premier hook mentionné dans la plupart des tutoriels d’introduction, sans se demander si leur traitement dépend réellement d’un état garanti seulement plus tard dans le cycle. La question à se poser avant de choisir un hook n’est pas « est-ce que ça marche en test », mais « quelle garantie précise ce hook m’offre-t-il, documentée noir sur blanc ».

Un test simple pour vérifier une hypothèse d’ordre

Avant de choisir un hook pour un traitement qui dépend d’une autre extension, il est utile d’ajouter temporairement une trace de journalisation dans les deux hooks candidats, afin d’observer concrètement l’ordre réel d’exécution sur l’environnement de production, pas seulement sur l’environnement de développement où l’ensemble des plugins actifs peut différer.

add_action('init', function () {
    error_log('init : personnalisation_filtres_actifs existe = '
        . (function_exists('personnalisation_filtres_actifs') ? 'oui' : 'non'));
}, 999);

add_action('wp_loaded', function () {
    error_log('wp_loaded : personnalisation_filtres_actifs existe = '
        . (function_exists('personnalisation_filtres_actifs') ? 'oui' : 'non'));
});

Sur ce projet, cette trace a confirmé sans ambiguïté que la fonction attendue n’existait pas encore au moment de init avec une priorité tardive de 999, mais qu’elle existait bien systématiquement dès wp_loaded, validant le choix du correctif retenu avant même de le déployer en production.

En résumé

Le choix d’un hook de chargement ne doit jamais reposer sur l’ordre observé empiriquement sur un site donné, cet ordre pouvant changer avec l’activation d’une nouvelle extension. Il doit reposer sur la garantie documentée de ce hook : ce qui est certainement chargé avant lui, et ce qui ne l’est pas forcément.

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