# 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.

- Auteur : WordPress Développement
- Publié le : 2021-01-15
- Mis à jour le : 2021-01-15
- Catégorie : Performance
- URL : https://www.wpmoderne.fr/performance/wp-defer-term-counting-import-categories/

## L’essentiel

- 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 )` : 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.
