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

Performance

wp_defer_term_counting accélère un import massif de catégories

Un import qui recalcule le nombre d'articles par catégorie à chaque insertion peut être considérablement accéléré en différant ce comptage jusqu'à la fin de la boucle.

Par WordPress Développement • 15 janvier 2021 • 4 min de lecture • Aucun commentaire
wp_defer_term_counting accélère un import massif de catégories

wp_defer_term_counting( true ) : cette instruction, placée en tête d’un script d’import de catégories, suffit souvent à transformer un traitement pénible en une opération rapide. Elle agit sur un mécanisme précis : le recomptage du nombre d’articles associés à chaque terme de taxonomie, déclenché par défaut à chaque insertion ou modification.

Le cas rencontré : un site éditorial important une arborescence de plusieurs milliers de catégories et sous-catégories depuis un système externe, avec des relations parents-enfants complexes. L’import, censé prendre quelques minutes, s’étirait sur plus d’une heure.

Ce que fait le comptage de termes à chaque insertion

Quand un article est associé à une catégorie via wp_set_object_terms(), ou quand une catégorie est créée ou modifiée via wp_insert_term(), WordPress recalcule par défaut le nombre d’articles rattachés à ce terme, ainsi qu’à ses parents dans la hiérarchie. Ce recomptage remonte la chaîne de parenté : une sous-catégorie de troisième niveau déclenche potentiellement trois recalculs en cascade à chaque insertion.

Pour une arborescence profonde avec plusieurs milliers de créations dans une même session, ce mécanisme, pensé pour rester à jour en toute circonstance sur un usage normal du site, devient un goulet d’étranglement pur pendant un import massif.

Le correctif : différer puis recalculer une seule fois

La fonction wp_defer_term_counting() permet de suspendre ce recalcul immédiat le temps de l’import, puis de forcer un recomptage global unique à la fin :

L'essentiel à retenir : Chaque insertion de terme déclenche par défaut un recomptage immédiat des articles associés ; wp_defer_term_counting( true ) reporte ce calcul à la fin du traitement ; Le gain grimpe avec le nombre de termes créés dans une même session
wp_defer_term_counting( true );

foreach ( $categories_source as $categorie ) {
    $parent_id = site_resoudre_parent( $categorie['parent'] );

    wp_insert_term(
        $categorie['nom'],
        'category',
        array( 'parent' => $parent_id )
    );
}

wp_defer_term_counting( false ); // déclenche le recomptage global ici

WP_CLI::success( count( $categories_source ) . ' catégories importées.' );

Le recomptage global déclenché par wp_defer_term_counting( false ) reste plus coûteux qu’un recomptage isolé, mais il ne s’exécute qu’une seule fois pour l’ensemble de l’import, au lieu de se répéter à chaque insertion.

Variantes selon le nombre de termes

Pour une dizaine de catégories créées ponctuellement, l’effet reste anecdotique et ne justifie pas la précaution. Le gain devient perceptible à partir de quelques centaines de termes, et franchement significatif au-delà du millier, en particulier lorsque la hiérarchie comporte plusieurs niveaux de profondeur.

  • Import à plat, sans hiérarchie : le gain reste modéré, le recomptage ne remontant aucune chaîne de parenté.
  • Import hiérarchique sur deux ou trois niveaux : le gain devient net, chaque insertion évitant plusieurs recalculs en cascade.
  • Import combiné avec des associations d’articles aux termes : combiner cette technique avec wp_defer_comment_counting() si des commentaires sont également importés en masse.

Vérifier le résultat après import

Une fois l’import terminé, il reste prudent de contrôler que le recomptage final s’est bien exécuté sur l’ensemble des termes créés, en comparant par exemple le nombre d’articles annoncé pour une catégorie donnée dans l’administration avec un comptage manuel via une requête directe. Un écart signale généralement un appel à wp_defer_term_counting( false ) manquant sur un chemin de sortie anticipé du script, un piège comparable à celui rencontré avec switch_to_blog() mal refermé.

Sur les imports particulièrement volumineux, il peut être utile de découper le recomptage final lui-même en le déclenchant par lots de catégories plutôt qu’en une seule passe globale, pour éviter qu’un script en ligne de commande ne dépasse la limite de temps d’exécution allouée au processus PHP.

Ce que cette technique ne couvre pas

Les métadonnées associées aux termes, si le projet en utilise, ne bénéficient d’aucun mécanisme de report équivalent natif : leur écriture continue de s’exécuter normalement à chaque insertion, et un éventuel goulet de ce côté demande un traitement séparé.

Différer un calcul jusqu’à la fin d’une boucle ne le rend pas gratuit : il devient simplement unique au lieu de répété, ce qui change tout sur un grand volume.

En résumé

Encadrer un import de taxonomies avec wp_defer_term_counting( true ) puis wp_defer_term_counting( false ) reporte le recomptage des articles associés à la toute fin du traitement, au lieu de le répéter à chaque insertion. Sur un import de quatre mille catégories imbriquées, le temps total a été réduit de plus des deux tiers, un gain qui grandit encore avec la profondeur de la hiérarchie importée.

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