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

Thèmes

WP_HTML_Tag_Processor injecte un lazy-load dans un vieux thème, via the_content

Injecter loading=lazy sur les images d'un thème hérité grâce à la classe WP_HTML_Tag_Processor de WordPress 6.2, sans réécrire le moteur de rendu.

Par WordPress Développement • 4 décembre 2023 • 4 min de lecture • Aucun commentaire
WP_HTML_Tag_Processor injecte un lazy-load dans un vieux thème, via the_content

class WP_HTML_Tag_Processor — cette simple ligne, apparue dans le cœur de WordPress avec la version 6.2, a changé ma façon de corriger de vieux thèmes sans toucher à leurs templates. Avant, modifier le HTML généré par the_content voulait dire manipuler des expressions régulières fragiles ou charger DOMDocument, avec son lot d’avertissements sur du HTML mal formé. Ce n’est plus nécessaire.

Le cas concret : un thème client vieux de plusieurs années, sans aucune gestion de chargement différé sur les images du contenu, hérité d’une génération de sites où cette pratique n’était pas encore un réflexe. Réécrire le moteur de rendu du contenu était hors budget ; injecter l’attribut au bon endroit via un filtre l’était beaucoup moins.

Pourquoi ne pas simplement activer le lazy-load natif du cœur

Le lazy-load natif de WordPress, actif par défaut depuis la 5.5, s’applique aux images insérées via la bibliothèque de médias avec les fonctions de balisage du cœur. Mais dans ce thème hérité, une partie des images du contenu provenait d’un ancien import qui avait figé le HTML sans passer par les fonctions habituelles, et une extension tierce désactivait par ailleurs le filtre natif pour des raisons de compatibilité avec un plugin de accélération de page. Le résultat : des images jamais concernées par le lazy-load automatique.

Plutôt que de démêler ce conflit avec l’extension tierce, j’ai choisi de reprendre la main directement sur le contenu affiché, en amont de l’affichage final.

L'essentiel à retenir : Analyseur HTML natif sans DOMDocument ni expressions régulières ; Filtre branché sur the_content, aucune modification de template ; Compatible avec un thème vieux de plusieurs années

Parcourir le contenu avec WP_HTML_Tag_Processor

La classe fonctionne comme un curseur qui se déplace de balise en balise dans une chaîne HTML, sans construire d’arbre DOM complet. On la positionne sur chaque balise img avec next_tag(), puis on ajoute l’attribut manquant avec set_attribute().

add_filter( 'the_content', function ( $contenu ) {
    $processeur = new WP_HTML_Tag_Processor( $contenu );

    while ( $processeur->next_tag( 'img' ) ) {
        if ( null === $processeur->get_attribute( 'loading' ) ) {
            $processeur->set_attribute( 'loading', 'lazy' );
        }
    }

    return $processeur->get_updated_html();
} );

La vérification get_attribute( 'loading' ) avant l’écriture évite d’écraser un réglage déjà présent sur certaines images (par exemple celles volontairement marquées eager pour l’image mise en avant). C’est ce genre de détail qui distingue un correctif propre d’un correctif qui casse une exception légitime.

Exclure la première image pour ne pas pénaliser le LCP

Ajouter loading="lazy" à toutes les images sans distinction dégrade souvent le Largest Contentful Paint lorsque l’image concernée est visible dès le chargement de la page. J’ai donc ajouté un compteur pour ignorer la première occurrence :

$processeur = new WP_HTML_Tag_Processor( $contenu );
$index = 0;

while ( $processeur->next_tag( 'img' ) ) {
    $index++;

    if ( 1 === $index ) {
        continue;
    }

    if ( null === $processeur->get_attribute( 'loading' ) ) {
        $processeur->set_attribute( 'loading', 'lazy' );
    }
}

Cette nuance a suffi à faire remonter le score Core Web Vitals du site sans toucher une seule ligne des templates existants du thème.

Les limites de l’approche

  • Le curseur ne traite qu’une balise à la fois : impossible de raisonner sur la hiérarchie parent-enfant comme avec un DOM complet.
  • Le filtre s’applique à chaque affichage de the_content, donc à chaque requête si aucun cache de page n’est en place ; un cache d’objet ou de page reste recommandé pour un site à fort trafic.
  • Le contenu doit rester un minimum bien formé : des balises jamais fermées peuvent perturber le repérage, même si la classe est tolérante sur ce point.

Une méthode transposable à d’autres attributs

Au-delà du lazy-load, la même classe permet d’ajouter des attributs decoding="async", de nettoyer des classes CSS orphelines laissées par un ancien éditeur, ou d’injecter rel="noopener" sur des liens externes oubliés — toujours sans réécrire les templates concernés.

Sur un thème hérité, je préfère toujours ce type de filtre ciblé à une réécriture complète du moteur de rendu : le risque de régression est bien plus faible, et le correctif tient dans une vingtaine de lignes de functions.php.

Notre verdict

WP_HTML_Tag_Processor est l’outil qu’il fallait pour ce genre de correctif ciblé sur un vieux thème : pas de dépendance externe, pas de réécriture de gabarit, un comportement prévisible même sur du HTML imparfait. Pour toute modification ponctuelle du balisage généré par the_content, c’est aujourd’hui mon premier réflexe avant d’envisager une extension tierce.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi