Problème posé par un client éditeur de contenu : sa page d’accueil, construite sur un thème block personnalisé exploitant pleinement theme.json, affichait un texte invisible pendant plus d’une seconde à chaque chargement, avant que la police variable personnalisée du thème ne finisse par apparaître. Ce phénomène, connu sous le nom de FOIT, pour « Flash of Invisible Text », dégradait particulièrement l’expérience sur connexion mobile plus lente.
La déclaration de la police dans theme.json, introduite plus largement avec l’éditeur de site, définit bien la police à utiliser pour le thème, mais elle ne déclenche aucun préchargement automatique de cette ressource par le navigateur, une confusion fréquente chez les développeurs qui découvrent ce fichier de configuration.
Ce que fait réellement theme.json pour les polices
La section settings.typography.fontFamilies de theme.json permet de déclarer une police, avec ses variantes de graisse et de style, référençant un fichier .woff2 situé dans le thème. WordPress génère à partir de cette déclaration une règle CSS @font-face correcte, injectée dans le CSS global du thème. Mais cette règle @font-face ne fait que décrire la police au navigateur : elle ne provoque son téléchargement qu’au moment où le CSS est appliqué à un élément visible, ce qui arrive relativement tard dans le cycle de chargement d’une page, après le CSS lui-même et son analyse.
Diagnostiquer le délai avec les DevTools
L’onglet Réseau des Chrome DevTools, filtré sur les polices, permettait de visualiser précisément le moment où le fichier .woff2 commençait à être demandé par rapport au début du chargement de la page : autour de 900 millisecondes, largement après le CSS et le HTML initial, à cause de la chaîne de dépendance CSS puis police.

La recette : générer le preload manquant
La solution a consisté à ajouter manuellement une balise de préchargement pour cette police, en s’assurant que le chemin corresponde exactement au fichier référencé dans theme.json, avec le bon type MIME et l’attribut crossorigin requis même sur un domaine identique pour les polices :
function theme_preload_police_variable() {
$chemin = get_theme_file_uri( 'assets/fonts/texte-variable.woff2' );
echo '<link rel="preload" href="' . esc_url( $chemin ) . '" as="font" type="font/woff2" crossorigin>' . "\n";
}
add_action( 'wp_head', 'theme_preload_police_variable', 1 );
Un deuxième ajustement complémentaire a consisté à définir la propriété CSS font-display: swap sur la règle @font-face générée, afin qu’en cas de réseau particulièrement lent, le texte s’affiche malgré tout avec une police de repli plutôt que de rester invisible indéfiniment. Cette propriété n’étant pas configurable directement depuis theme.json à l’époque, un petit filtre a permis de la surcharger après génération du CSS :
add_filter( 'wp_theme_json_data_theme', function ( $donnees ) {
$theme_json = $donnees->get_data();
foreach ( $theme_json['settings']['typography']['fontFamilies'] as &$police ) {
foreach ( $police['fontFace'] as &$face ) {
$face['fontDisplay'] = 'swap';
}
}
return $donnees->update( $theme_json );
} );
Vérifier le résultat
Après ajout du preload, l’onglet Réseau montrait le fichier de police demandé en parallèle du CSS, plutôt qu’après son analyse complète. Le temps de texte invisible mesuré avec l’outil « Rendering » des DevTools est passé de 1,2 seconde à moins de 150 millisecondes, un délai qui correspond désormais essentiellement au temps de téléchargement réel du fichier de police sur la connexion testée.
- Une déclaration dans
theme.jsonne suffit jamais à elle seule à garantir un chargement rapide de la police. - Le preload doit correspondre exactement au fichier réellement utilisé sur la première vue de la page.
font-display: swapreste une sécurité complémentaire utile, indépendamment du preload.
Pour aller plus loin
La Font Library, introduite plus tard avec WordPress 6.5, changera en partie la façon dont les polices sont gérées et hébergées dans l’éditeur de site, avec potentiellement une gestion de préchargement plus intégrée à terme. À la date de ce cas, elle n’existe pas encore, et la solution manuelle décrite ici reste la voie la plus fiable pour un thème block personnalisé exploitant theme.json.
En résumé
Une police variable déclarée proprement dans theme.json peut malgré tout provoquer un FOIT marqué si aucun preload n’est ajouté explicitement. Ce correctif, léger en code, élimine un délai d’affichage qui pénalise directement la perception de rapidité du site par ses visiteurs, sans rapport avec le contenu lui-même.