L’en-tête Server-Timing existe dans la spécification du W3C depuis des années et reste pourtant sous-utilisé sur WordPress, alors qu’il permet d’exposer, directement dans l’onglet Réseau des DevTools d’un navigateur, des mesures de temps serveur normalement enfouies dans des logs séparés. Ce billet documente un snippet qui combine cet en-tête avec les traces déjà collectées par Sentry Performance, pour isoler rapidement la couche responsable d’une lenteur signalée par un client sans avoir à reproduire l’incident en environnement contrôlé.
Ce snippet suppose que Sentry est déjà installé et fonctionnel sur le site ; sa mise en place initiale ne fait pas l’objet de ce billet, qui se concentre uniquement sur l’exposition complémentaire via Server-Timing.
Le problème que ce snippet résout
Une trace Sentry Performance donne une vue complète, mais elle demande d’ouvrir le tableau de bord Sentry, de retrouver la transaction correspondante, puis de croiser manuellement avec le comportement observé côté navigateur. Pour un diagnostic rapide en pleine investigation, disposer directement dans l’onglet Réseau du navigateur d’un résumé des temps par couche (base de données, cache, hooks WordPress, rendu du template) accélère considérablement le premier tri, avant même de creuser dans Sentry.
Le snippet commenté

<?php
/**
* Expose les temps de génération WordPress via Server-Timing,
* en cohérence avec l'identifiant de transaction Sentry actif.
*/
add_action( 'init', function () {
global $wp_timing_marqueurs;
$wp_timing_marqueurs = [ 'debut' => microtime( true ) ];
});
add_action( 'wp_loaded', function () {
global $wp_timing_marqueurs;
$wp_timing_marqueurs['hooks'] = microtime( true );
});
add_action( 'send_headers', function () {
global $wp_timing_marqueurs, $wpdb;
$temps_bdd = $wpdb->timer_stop( 0 ) ?? 0;
$temps_hooks = ( $wp_timing_marqueurs['hooks'] ?? microtime( true ) ) - $wp_timing_marqueurs['debut'];
$temps_total = microtime( true ) - $wp_timing_marqueurs['debut'];
$temps_rendu = max( 0, $temps_total - $temps_hooks );
$transaction_sentry = \Sentry\SentrySdk::getCurrentHub()
->getSpan()?->getTraceId() ?? 'inconnue';
header( sprintf(
'Server-Timing: bdd;dur=%.1f, hooks;dur=%.1f, rendu;dur=%.1f, total;dur=%.1f',
$temps_bdd * 1000,
$temps_hooks * 1000,
$temps_rendu * 1000,
$temps_total * 1000
), false );
header( 'X-Sentry-Trace-Id: ' . $transaction_sentry );
});
La ligne X-Sentry-Trace-Id n’est pas une convention standard de Server-Timing, mais un en-tête maison qui permet, une fois collé dans la barre de recherche du tableau de bord Sentry, de retrouver instantanément la transaction correspondant à la requête inspectée dans les DevTools — évitant l’étape fastidieuse de recherche par horodatage approximatif.
Lecture dans les DevTools
Une fois ce snippet actif, l’onglet Réseau des DevTools Chrome ou Firefox affiche, dans le panneau « Timing » de chaque requête de document, une section « Server Timing » listant les quatre métriques exposées. Sur une requête qui semblait globalement lente au chargement, il devient immédiat de voir si le temps est concentré sur la base de données, sur l’exécution des hooks, ou sur le rendu du template — sans avoir eu besoin d’installer Query Monitor ou d’activer un mode de débogage supplémentaire chez le client qui a signalé le ralentissement.
Corréler avec la trace Sentry complète
Une fois l’identifiant de trace récupéré dans les DevTools (en-tête X-Sentry-Trace-Id), une recherche directe dans Sentry via ce même identifiant ouvre la transaction complète, avec le détail span par span. Le résumé Server-Timing sert alors de premier filtre grossier — « c’est la base de données qui domine » — et la trace Sentry apporte le détail fin — quelle requête précise, quel plugin l’a déclenchée.
Limites à connaître
- Le temps mesuré par
$wpdb->timer_stop()ne couvre que les requêtes passées par la classewpdb; un appel direct via l’extensionmysqlien dehors de ce mécanisme échapperait à la mesure. - Exposer ces temps publiquement sur un site en production révèle une information d’architecture interne ; il est recommandé de conditionner l’affichage de l’en-tête à un utilisateur connecté avec une capacité spécifique (
current_user_can( 'manage_options' )) plutôt qu’à tous les visiteurs. - Ce snippet mesure des temps serveur, pas le temps réseau ni le temps de rendu côté navigateur : il complète les Core Web Vitals sans s’y substituer.
Un en-tête de quelques dizaines d’octets peut faire gagner plusieurs minutes d’aller-retour entre les DevTools et un tableau de bord de monitoring.
En résumé
Ce couple Server-Timing / Sentry n’est pas un remplacement des outils de profilage classiques, mais un accélérateur de premier diagnostic, particulièrement utile lorsqu’un client signale une lenteur ponctuelle difficile à reproduire à la demande. La visibilité directe dans les DevTools, sans étape intermédiaire, change concrètement la vitesse à laquelle une première hypothèse peut être posée ou écartée.