Gestion à grande échelle des combinaisons et attributs de produits complexes dans PrestaShop

Quatre attributs pour un seul produit. Dix-neuf valeurs pour le premier, huit, huit et trois. Cela équivaut à 3 648 variantes d'un article, et ce n'est pas une simple hypothèse : un marchand a signalé exactement ce problème sur le système de suivi des problèmes de PrestaShop , concernant 30 produits et plus de 100 000 lignes de base de données.

Leurs pages produits ont expiré et l'interface d'administration a renvoyé un écran blanc. 

Rien n'était cassé. Le catalogue fonctionnait exactement comme prévu, à une échelle pour laquelle personne ne l'avait optimisé.

Le problème que beaucoup de propriétaires découvrent trop tard : les combinaisons de produits PrestaShop fonctionnent avec des exposants, et non des sommes. Dix valeurs dans un groupe et dix dans un autre donnent une centaine de variantes à tarifer, à gérer en stock et à photographier, et non vingt. Une gestion efficace des combinaisons de produits PrestaShop commence par là.

1.0 Attributs et combinaisons PrestaShop : quelle est la différence ?

Deux termes sont constamment confondus, et la différence entre les deux détermine la manière dont vous construisez votre catalogue.

Les attributs d'un produit PrestaShop sont les options choisies par le client : taille, couleur, capacité de stockage. Une caractéristique est un texte descriptif affiché sur la page et non sélectionnable : poids, matériau, pays d'origine. La documentation PrestaShop l'explique clairement : un client peut acheter une variante d'iPad en fonction de la couleur et de la capacité de stockage, mais pas en fonction du poids.

Une erreur de ce côté-là vous coûtera cher dans tous les cas. Si vous traitez une fonctionnalité comme un attribut, vous générez des centaines de variantes entre lesquelles personne ne choisira, chacune alimentant cinq tables. L'inverse est pire : les clients ne pourront pas acheter la version qu'ils souhaitaient.

La structure se compose de trois niveaux. Un groupe d'attributs, comme Taille, contient des valeurs telles que Petit et Moyen, et une combinaison correspond à une paire commune à tous les groupes. Dans le système, cela se traduit par une ligne dans product_attribute , contenant sa propre référence, son ajustement de prix, son poids et son stock.

2.0 Pourquoi les combinaisons de produits PrestaShop se multiplient-elles si rapidement ?

Le générateur de combinaisons PrestaShop produit le produit cartésien complet, c'est-à-dire la somme de chaque valeur de chaque groupe et de chaque autre valeur de chaque autre groupe. Le nombre de variantes de vos produits PrestaShop correspond à ces multiplications, et non à leur addition.

Vous verrez comme ça vous échappe rapidement.

Trois groupes, soixante variantes. Un quatrième groupe de trois valeurs porterait ce nombre à 180.

Groupes d'attributsValeurs dans chaqueCombinaisons créées
2 (Taille, Couleur)5 et 420
3 (Taille, Couleur, Matière)5, 4 et 360
4 (Taille, Couleur, Matériau, Finition)5, 4, 3 et 3180
4 (comme indiqué dans le numéro 12915)19, 8, 8 et 33,648

Ajoutez un autre groupe de trois valeurs et vous obtenez votre total de triplets. Il ne s'agit pas d'ajouter trois, mais de multiplier trois. Ce détail est la principale source d'erreurs chez les marchands dans la gestion des combinaisons PrestaShop.

À savoir avant de cliquer sur Générer : la plateforme n’impose aucune limite supérieure . Le générateur est récursif et produit les combinaisons une à une, sans qu’aucune limite maximale ne soit définie dans la classe.

3.0 Que fait la base de données lorsque vous générez des combinaisons ?

Une seule combinaison ne correspond jamais à une seule rangée. Loin de là. C'est le détail qui échappe à ceux qui consultent un catalogue surchargé et se demandent d'où viennent ces dimensions.

Générez une combinaison, et PrestaShop écrit dans cinq tables distinctes :

  • attribut_produit Elle renferme la combinaison elle-même, avec son impact de référence et de prix.
  • Les paramètres de prix et de stock spécifiques à chaque magasin sont intégrés dans attribut_produit_boutique, une rangée par magasin.
  • combinaison_d'attributs_de_produit relie la combinaison à ses valeurs d'attributs. Surtout, il s'agit de une ligne par attribut, donc une combinaison à quatre attributs écrit ici à elle seule quatre lignes.
  • Les actions vivent dans stock_disponible, encore une fois par magasin.
  • Enfin, des attribut_produit_lang stocke les étiquettes de disponibilité, une ligne par langue.

Cinq tableaux par combinaison, dont deux s'adaptent au nombre d'attributs et de langues.

Effectuez maintenant les calculs sur ce produit à 3 648 combinaisons, en supposant quatre attributs, deux langues et une boutique. Vous obtenez 3 648 lignes pour `product_attribute`, 3 648 autres pour `product_attribute_shop`, 14 592 pour `product_attribute_combination`, 3 648 pour `stock_available` et 7 296 pour `product_attribute_lang`. Cela représente 32 832 lignes pour un seul produit.

Multipliez par 30 produits, et vous approchez le million de lignes. Le commerçant mentionné dans ce numéro en a déclaré plus de 100 000, ce qui le place dans la fourchette basse.

Le nombre de langues et de boutiques multiplie à nouveau le total ; ainsi, gérer trois langues dans deux boutiques n’ajoute pas grand-chose à la gestion des variantes de produits PrestaShop . Plusieurs de ces décomptes se multiplient directement.

4.0 Performances combinées de PrestaShop pour les catalogues volumineux

Le stockage est bon marché, et un million de lignes ne représentent rien pour une base de données. Alors pourquoi ces pages produits ont-elles été indexées ?

La réponse se trouve chez le contrôleur de gestion du front office, et elle est plus spécifique qu'une simple lenteur générale.

Lorsqu'un client ouvre une page produit, PrestaShop appelle la fonction `getAttributesGroups()` sans filtre, limitant ainsi la recherche aux combinaisons affichées à l'écran. Toutes les combinaisons possibles pour ce produit sont alors renvoyées. Soit les 3 648, à chaque affichage de la page, avant même que le visiteur n'ait cliqué sur quoi que ce soit.

Le prix augmente ensuite. Le contrôleur parcourt ces lignes et appelle `Product::getPriceStatic()` une fois par combinaison pour déterminer si un prix spécifique s'applique. Près de quatre mille calculs de prix, chacun intégrant sa propre logique de taxes et de remises, sont nécessaires pour afficher une seule page.

Ici, rien ne dépend du choix du visiteur. Le travail se fait dans les deux cas.

Les développeurs de PrestaShop sont au courant. Juste au-dessus de cette requête dans le code source de la version 8.2.6 se trouve un commentaire d'un mainteneur principal demandant si le code devrait récupérer uniquement les groupes plutôt que chaque variante. Cette question est présente dans le code depuis des années.

Deux conséquences pratiques découlent de cette conception :

  • Le temps de chargement d'une page dépend du nombre de combinaisons possibles, et non des choix du client. Un produit avec 3 600 variantes sera lent à charger, même pour un visiteur qui quitte immédiatement la page.
  • Des règles tarifaires spécifiques aggravent la situation, car chacune ajoute du travail à une boucle qui s'exécute déjà des milliers de fois. C'est le principal piège. Gestion des combinaisons de catalogues volumineux PrestaShop.

Bon à savoir : une boutique sans combinaisons ignore complètement la requête, car Combination::isFeatureActive() renvoie une valeur prématurée.

5.0 Comment gérer des milliers de combinaisons de produits dans PrestaShop

5.1 Réduisez le nombre d'attributs avant toute autre chose

Chaque groupe que vous supprimez divise votre total, c'est donc le changement qui a le plus grand impact, et il ne coûte techniquement rien.

Pour chaque groupe, posez-vous une question directe : un client refusera-t-il d’acheter s’il ne peut pas choisir cette option ? La finition, le type d’emballage et le nombre de fils échouent généralement à ce test. Intégrez-les dans la catégorie « Caractéristiques ».

Supprimez un groupe de trois valeurs de ce produit de 3 648 combinaisons, et vous arrivez à 1 216. Une seule décision, et les deux tiers des lignes disparaissent.

5.2 Diviser en produits distincts lorsqu'une variante est en réalité un produit

Pour les véritables variations d'un même article, les attributs sont appropriés. Dès lors que les options diffèrent suffisamment pour que les clients les recherchent séparément, ou si vous souhaitez des photos et des URL distinctes, il s'agit de produits distincts arborant une simple variante.

Des produits séparés sont également mieux référencés, car chacun possède sa propre URL et sa propre méta-description. Un produit combiné n'en possède aucun.

5.3 Générer, puis modifier en masse

Pour la gestion des combinaisons de produits en masse dans PrestaShop , le générateur est bien plus efficace que la création manuelle de variantes. Générez l'ensemble complet, puis supprimez les produits indisponibles : c'est le principe même de la gestion des combinaisons de produits en masse dans PrestaShop . Lors de la génération, PrestaShop désactive certaines règles de prix et les applique en une seule étape à la fin, ce qui rend le premier traitement plus rapide qu'il n'y paraît.

La régénération d'un ensemble existant se comporte différemment. Avant de créer chaque combinaison, PrestaShop interroge la base de données pour vérifier si cette paire d'attributs existe déjà. Des milliers de combinaisons, des milliers de recherches. D'où la sensation de lenteur bien plus importante lors de la deuxième exécution.

5.4 Lorsqu'une combinaison est totalement inadaptée

La suppression de groupes d'attributs soulève une question évidente : qu'advient-il de l'option que vous venez de supprimer ? Parfois, elle devient une fonctionnalité. Parfois, aucune des deux options ne convient.

Gravure de texte, monogramme, date de livraison, logo téléchargé : ces éléments ne peuvent être combinés, car une combinaison nécessite une liste finie de valeurs définies au préalable.

Ces éléments doivent figurer dans un champ de produit personnalisé, que PrestaShop appelle une personnalisation :

  • Une combinaison est finie, définie à l'avance et contient du stock. Chacune coûte des lignes réparties sur cinq tables.
  • Champ ouvert et rempli par votre client : ce champ personnalisé n’occupe aucun espace dans votre stock et coûte le même prix pour les produits comportant 3 variantes que pour ceux en comportant 3 000.

Les deux éléments sont liés. Un t-shirt peut comporter la taille et la couleur, ainsi qu'un nom imprimé en tant que champ personnalisé ; les deux informations apparaissent sur la ligne de commande.

Il est important de noter un point essentiel : PrestaShop identifie une ligne de panier par produit et combinaison. Ainsi, deux clients commandant la même tasse avec des gravures différentes seront regroupés en une seule ligne de quantité deux. Les modules qui gèrent ce cas redéfinissent les méthodes `Cart::updateQty` , `Cart::getProducts` et `Cart::deleteProduct` , puis hachent les valeurs soumises afin de maintenir les lignes distinctes.

5.5 Deux problèmes qui n'apparaissent qu'une fois la commande passée

La commande stocke la combinaison dans le nom du produit. Lors de la passation d'une commande, PrestaShop ne conserve pas de référence à la combinaison pour la rechercher ultérieurement. Il écrit la combinaison dans le nom et stocke cette chaîne de caractères ; ainsi, order_detail.product_name contient finalement quelque chose comme « T-shirt imprimé colibri (Taille : S – Couleur : Blanc) ».

Chaque attribut défini pour un champ allonge la chaîne de caractères d'un élément, chaque valeur et chaque groupe étant ajouté. Quatre groupes allongent considérablement un nom déjà long.

Le problème réside dans la largeur des colonnes, et celle-ci varie selon votre version de PrestaShop.

Dans PrestaShop 1.7, la largeur de la colonne est de type varchar(255). Les versions 8 et 9 utilisent le type MEDIUMTEXT. Il semble également que la taille varchar de ce champ ne soit pas déclarée dans la version 1.7 ; sa longueur n'est donc pas vérifiée avant l'insertion et est simplement tronquée par MySQL après 255 caractères.

Personne ne remarque l'erreur. La commande est enregistrée, et la perte apparaît plus tard sur la facture ou dans la liste des commandes, où deux variantes peuvent sembler identiques car l'élément qui les distingue est la pièce manquante. La mise à jour vers une version supérieure à 1.7 supprime cette limitation.

Le texte de personnalisation est transmis à l'e-mail de confirmation sous forme de chaîne de caractères. PrestaShop génère dynamiquement ce texte en PHP avec le balisage souhaité, les libellés étant insérés et les entrées délimitées par <br />. Le modèle d'e-mail affiche ensuite la valeur sans utiliser de caractères spéciaux, et comme les modèles d'e-mail sont exécutés avec l'échappement Smarty activé, toutes ces balises sont transformées en entités.

Le client lit les étiquettes au lieu de voir un libellé en gras et un saut de ligne. Envoyez-vous une commande test avec un produit personnalisé : la même commande s’affichera correctement sur la facture PDF alors que l’e-mail affichera le code brut.

5.6 Surveillez l'évolution des prix spécifiques

Chaque règle de tarification spécifique ajoute du travail à la boucle de calcul par combinaison, ce qui explique pourquoi quelques règles sont sans conséquence sur un petit catalogue, mais deviennent le principal problème sur un catalogue important. Prenons l'exemple du marchand du numéro 12915 : un prix personnalisé différent pour chacune des 3 600 variantes.

Lorsqu'une différence de prix s'applique à un groupe entier, utilisez le champ « Impact du prix combiné » plutôt qu'une règle de prix spécifique. Ce champ figure sur la ligne de la combinaison et sa lecture est gratuite.

6.0 Qu'est-ce qui a changé entre PrestaShop 1.7 et 9 ?

Il y en a beaucoup, et les différences sont importantes si vous suivez un tutoriel plus ancien.

Dans PrestaShop 9, l'ancienne page produit a disparu. Seule la page repensée introduite dans la version 1.7 et améliorée dans la série 8.x l'a remplacée. Les notes de développement de la version 9.0 confirment que l'ancienne page est désormais inaccessible. Par conséquent, toutes les captures d'écran des tutoriels antérieurs à cette version présentent une interface qui n'est plus disponible.

Les auteurs de modules ont encore des vérifications à effectuer. Tous les hooks liés à l'ancienne page produit ont disparu avec la version 9.0, notamment la famille `actionAdminProductsController` . Si vous utilisez l'un d'eux pour la gestion des combinaisons, ce module doit être réécrit.

Deux modifications de données peuvent également poser problème. L'attribut `price` a disparu de `Product::getProductProperties` , et les fonctionnalités ne sont plus incluses par défaut dans `getProductsProperties`. Ces deux erreurs sont silencieuses.

Côté performances, une bonne nouvelle : PrestaShop 9.1 propose une amélioration significative des performances du panier pour les boutiques avec de nombreuses combinaisons de produits , comme l'indiquent ses notes de version . Vous gérez un catalogue de variantes important sur la version 9.0 ? À lui seul, il justifie la mise à niveau.

Un changement de schéma est important si vous êtes encore sur la version 1.7. La colonne order_detail.product_name était varchar(255) sur cette version et est MEDIUMTEXT sur les versions 8 et 9, la mise à niveau supprime donc la troncature silencieuse décrite ci-dessus.

Le comportement fondamental n'a cependant pas changé. Les combinaisons restent un produit cartésien, sans limite, réparti sur les mêmes cinq tables, et le fait de compter avant de générer est tout aussi important sur la version 9 que sur la version 1.7.

7.0 Un ordre pratique pour travailler dans

Face à un catalogue devenu ingérable, procédez par étapes. Voici la réponse courte à la question : comment gérer un grand nombre de variantes de produits dans PrestaShop ?

  1. Commencez par compter. Multipliez les valeurs de vos attributs avant de cliquer sur Générer. Si vous dépassez quelques centaines de valeurs pour un même produit, arrêtez-vous et réfléchissez-y à deux fois.
  2. Un groupe d'attributs pourrait-il être une fonctionnalité ou un champ personnalisé ouvert ?
  3. Quelles variantes méritent leur propre page produit ? Tout ce que vous souhaitez trouver séparément dans les résultats de recherche.
  4. Vérifiez les règles tarifaires spécifiques aux produits à forte variante, en remplaçant autant que possible par le champ d'impact sur le prix combiné.
  5. Passez une commande test pour un produit comportant plusieurs attributs et une personnalisation, puis consultez le détail de la commande et l'e-mail de confirmation. Les noms longs sont tronqués sous Android 1.7 et l'e-mail échappe son propre balisage.
  6. Vous utilisez PrestaShop 9.0 avec un catalogue de variantes important ? Passez à la version 9.1 pour optimiser les performances du panier.

8.0 La version courte

Les combinaisons se multiplient, et cette multiplication impacte la base de données plus rapidement que la plupart des commerçants ne le prévoient. Cinq tables par combinaison. Un produit à quatre attributs avec quelques milliers de variantes peut contenir jusqu'à 30 000 lignes.

Le problème de performance se situe au niveau de la page produit, et non du stockage. PrestaShop charge chaque combinaison et calcule le prix de chaque article individuellement, à chaque affichage, que le visiteur ouvre ou non le menu déroulant.

La solution la plus efficace reste la plus simple. Moins de groupes d'attributs signifient un nombre exponentiellement inférieur de combinaisons ; effectuez donc la multiplication avant toute génération.

Merci pour la lecture.

Pour toute question ou assistance concernant les performances ou la migration de votre site web, nos experts sont à votre disposition. Contactez l'équipe Knowband à l'adresse [email protected] dès aujourd'hui pour obtenir des plugins e-commerce fiables et adaptés à vos besoins.

Laissez un commentaire