# Antipatterns de panier : appeler calculate_totals() à chaque rendu

> Recalculer les totaux du panier à chaque affichage d'un bloc, plutôt qu'une seule fois par requête, ralentit une boutique sans que la cause saute aux yeux dans le code.

- Auteur : WordPress Développement
- Publié le : 2021-04-23
- Mis à jour le : 2021-04-23
- Catégorie : E-commerce
- URL : https://www.wpmoderne.fr/ecommerce/antipattern-panier-recalcul-totaux-chaque-rendu/

## L’essentiel

- Le recalcul des totaux du panier a un coût réel, pas anodin
- Chaque bloc qui affiche le panier ne doit pas relancer son propre calcul
- Une mémorisation simple par requête suffit à corriger le problème

Un thème enfant affiche le panier à trois endroits différents sur la même page : un mini-panier dans l'en-tête, un récapitulatif dans une barre latérale, un total dans un bloc personnalisé en bas de page. Trois emplacements, trois appels indépendants à la logique de calcul du panier, alors qu'un seul aurait suffi. C'est exactement ce genre d'antipattern qui ralentit une boutique sans qu'aucun message d'erreur ne le signale.

Le symptôme se voit rarement en développement local, où le catalogue reste petit et la base de données légère. Il apparaît en production, sur un panier chargé de plusieurs dizaines d'articles avec des règles de tarification conditionnelle, quand chaque recalcul devient coûteux à l'échelle du serveur mutualisé qui héberge la boutique.

## Ce qu'on observe dans le code

Chaque bloc personnalisé qui affiche une information liée au panier — total, nombre d'articles, sous-total hors taxes — déclenche indépendamment le recalcul complet du panier via `WC()->cart->calculate_totals()`, souvent enveloppé dans une fonction utilitaire appelée à chaque fois qu'un template a besoin d'un chiffre. Rien n'empêche techniquement ce fonctionnement : WordPress ne se plaint jamais d'un recalcul redondant, il l'exécute simplement, encore et encore.

Sur une page qui affiche le panier à trois endroits, on obtient donc trois recalculs complets pour une seule visite de page, chacun repassant par le calcul des taxes, des remises, des frais de port éventuels et des coupons appliqués. Multiplié par le nombre de visiteurs actifs simultanément, ce comportement pèse sur le temps de réponse du serveur sans qu'aucune requête individuelle ne semble anormalement lente à elle seule.

## Pourquoi c'est un problème réel, pas un détail théorique

Le calcul des totaux d'un panier WooCommerce n'est pas une simple addition : il parcourt chaque article, applique les règles de taxation selon la localisation du client, évalue les coupons actifs et leurs conditions, puis recalcule les frais de port si une méthode dépendante du contenu du panier est configurée. Sur un panier de taille modeste, l'opération reste rapide ; répétée plusieurs fois par requête, sur un catalogue avec des règles de tarification personnalisées ajoutées par des hooks maison, le coût cumulé devient mesurable.

> L'essentiel à retenir : Le recalcul des totaux du panier a un coût réel, pas anodin ; Chaque bloc qui affiche le panier ne doit pas relancer son propre calcul ; Une mémorisation simple par requête suffit à corriger le problème

### Un cas particulièrement coûteux : les hooks personnalisés

Le problème s'aggrave nettement quand une boutique a ajouté ses propres règles via `woocommerce_before_calculate_totals`, par exemple pour appliquer une remise dégressive selon la quantité totale d'articles. Ce hook s'exécute à chaque appel de `calculate_totals()` : trois appels redondants sur une même page multiplient donc aussi par trois l'exécution de cette logique personnalisée, potentiellement plus lourde qu'un simple calcul de taxe standard.

## Le correctif : mémoriser le résultat par requête

La correction ne consiste pas à supprimer les appels au calcul du panier, mais à s'assurer qu'un seul recalcul a lieu par requête, ses résultats étant ensuite réutilisés partout où c'est nécessaire. Une variable statique simple, ou une propriété d'une classe utilitaire instanciée une fois, suffit à éviter la répétition.

```
function get_totaux_panier_memorises() {
    static $totaux = null;

    if ( null === $totaux ) {
        WC()->cart->calculate_totals();
        $totaux = array(
            'sous_total' => WC()->cart->get_subtotal(),
            'total'      => WC()->cart->get_total( 'raw' ),
        );
    }

    return $totaux;
}
```

- Repérer chaque bloc de template qui déclenche indépendamment un calcul de panier
- Centraliser l'appel au calcul dans une seule fonction mémorisée par requête
- Vérifier l'impact réel des hooks personnalisés attachés au calcul des totaux

## Un piège voisin : les fragments AJAX du mini-panier

Le mini-panier mis à jour en AJAX via `woocommerce_add_to_cart_fragments` peut lui aussi provoquer un recalcul distinct de celui déclenché par le rendu de la page principale. Il faut vérifier que ce fragment réutilise l'objet panier déjà chargé en mémoire pour la requête AJAX en cours, plutôt que de forcer un nouveau calcul complet à chaque fragment généré.

> Un panier ne devrait jamais se recalculer plus d'une fois par requête : au-delà, chaque appel supplémentaire est du travail serveur offert gratuitement à personne.

## Ce que ce correctif ne règle pas

Cet article se concentre sur le recalcul redondant du panier, pas sur la configuration fiscale elle-même : le nombre de règles de taxe actives, leur complexité géographique ou la présence de plusieurs classes de taxes sont des sujets indépendants qui influencent aussi la performance, mais qui se traitent séparément du problème de répétition décrit ici.

## En résumé technique

Ce type d'antipattern se glisse facilement dans un thème développé par petites touches successives, chaque développeur ajoutant son propre bloc sans vérifier ce qui existe déjà ailleurs sur la page. Un audit rapide des appels à `calculate_totals()` dans le code d'un thème suffit souvent à repérer ces doublons et à les corriger en une intervention limitée.
