Un site météo local avait développé un bloc Gutenberg personnalisé affichant la météo du jour en en-tête de chaque article de blog, en interrogeant une API météo externe. Le bloc fonctionnait très bien en test, avec un seul article affiché à la fois. En production, sur une page de liste affichant dix articles, chacun avec sa propre instance du bloc, le temps de chargement de la page a commencé à dépasser cinq secondes par moments, en particulier lorsque l’API externe répondait plus lentement que d’habitude.
La particularité des blocs dynamiques, par opposition aux blocs statiques dont le rendu est figé au moment de la publication, est justement leur exécution à chaque affichage de la page côté serveur, via une fonction PHP enregistrée comme render_callback. C’est cette caractéristique qui, mal utilisée, a transformé un simple affichage météo en goulet d’étranglement.
Diagnostic avec Query Monitor
Query Monitor ne se limite pas aux requêtes SQL : son panneau « HTTP API Calls » liste chaque appel réseau sortant effectué pendant la génération de la page, avec son temps de réponse individuel. Sur la page de liste incriminée, dix appels distincts vers l’API météo apparaissaient, un par instance du bloc, avec des temps de réponse individuels variant entre 200 millisecondes et plus d’une seconde selon la charge du service tiers à cet instant.
Le code du bloc, simplifié, ressemblait à ceci :
register_block_type( 'monsite/meteo-du-jour', array(
'render_callback' => function ( $attributs ) {
$reponse = wp_remote_get( 'https://api.meteo-externe.fr/v1/actuelle?ville=' . $attributs['ville'] );
$donnees = json_decode( wp_remote_retrieve_body( $reponse ), true );
return '<p>Météo à ' . esc_html( $attributs['ville'] ) . ' : ' . esc_html( $donnees['temperature'] ) . ' °C</p>';
},
) );
Chaque affichage de la page relançait cet appel réseau, sans aucune mise en cache, ce qui explique pourquoi le temps de génération de la page variait fortement d’un chargement à l’autre, selon la disponibilité du service météo à cet instant précis.

Le correctif par transient
La météo d’une ville donnée ne change pas d’une seconde à l’autre, ce qui rendait un cache de quelques minutes largement acceptable pour l’usage réel. Le correctif a consisté à envelopper l’appel réseau dans un transient, avec une durée de quinze minutes, jugée pertinente pour ce cas d’usage :
register_block_type( 'monsite/meteo-du-jour', array(
'render_callback' => function ( $attributs ) {
$cle_transient = 'meteo_' . sanitize_key( $attributs['ville'] );
$donnees = get_transient( $cle_transient );
if ( false === $donnees ) {
$reponse = wp_remote_get( 'https://api.meteo-externe.fr/v1/actuelle?ville=' . $attributs['ville'], array(
'timeout' => 3,
) );
if ( ! is_wp_error( $reponse ) ) {
$donnees = json_decode( wp_remote_retrieve_body( $reponse ), true );
set_transient( $cle_transient, $donnees, 15 * MINUTE_IN_SECONDS );
}
}
if ( ! $donnees ) {
return '';
}
return '<p>Météo à ' . esc_html( $attributs['ville'] ) . ' : ' . esc_html( $donnees['temperature'] ) . ' °C</p>';
},
) );
Deux détails complémentaires ont été ajoutés : un timeout explicite de trois secondes sur l’appel réseau, pour éviter qu’une API externe en difficulté ne bloque le rendu de la page indéfiniment, et un retour silencieux, sans erreur visible, si l’appel échoue malgré tout.
Le résultat après correctif
Avec la clé de transient construite par ville, toutes les instances du bloc pour une même ville partagent désormais le même cache, ce qui réduit également le nombre d’appels réseau effectifs vers l’API météo, un bénéfice apprécié par le fournisseur de l’API lui-même dont les quotas d’appels commençaient à être sollicités. Le temps de génération de la page de liste est redescendu à moins de 400 millisecondes de façon stable.
- Ne jamais placer un appel réseau externe sans cache dans un
render_callbackappelé potentiellement plusieurs fois par page. - Toujours fixer un
timeoutexplicite sur les appels viawp_remote_get(). - Adapter la durée du transient à la fraîcheur réellement nécessaire de la donnée, pas par défaut à une heure.
En résumé
Un bloc dynamique reste un bloc de code PHP exécuté à chaque affichage, avec les mêmes règles de prudence que n’importe quelle autre partie de WordPress vis-à-vis des appels réseau. Ce cas ne traite pas les blocs statiques, dont le rendu est figé à la publication, ni la logique de rendu gérée via un script JavaScript propre au bloc côté client, qui répond à des règles de performance différentes.