Un développeur Magento a remplacé 300 appels distincts à ProductRepositoryInterface::getById() par une seule requête de collection. Le nombre d'appels à la base de données est passé de 300 à 1, et la page de catégorie s'est chargée nettement plus rapidement. Le revers de la médaille ? Certains produits ont disparu de la boutique, déroutant les clients et les propriétaires.

Le problème N+1 sur une page de catégorie Magento

La page affichait 300 produits. Pour chacun d'eux, le code récupérait deux attributs personnalisés via la méthode getById() du repository, générant ainsi une requête par produit — le schéma classique du N+1. Remplacer ces chargements par produit par une collection qui extrait toutes les lignes nécessaires en une seule requête a considérablement réduit le nombre de requêtes. La latence front-end s'est améliorée, mais la liste des produits ne contenait plus certains articles qui apparaissaient auparavant.

Pourquoi la collection masque les articles en rupture de stock

Le module CatalogInventory de Magento ajoute automatiquement un filtre « en stock » à toute collection de produits construite pour le front-end. Le filtre s'active lorsque le paramètre de la boutique Display Out of Stock Products est désactivé, un choix courant pour les marchands qui ne souhaitent pas afficher les articles indisponibles.

À l'inverse, le repository n'applique jamais de filtre de stock. Il vérifie simplement qu'un produit existe et le renvoie, quel que soit le niveau de stock. Lorsque le code est passé des appels au repository à une collection, le filtre de stock a silencieusement supprimé chaque produit dont la quantité était de zéro. Aucune erreur n'a été enregistrée ; la collection a simplement renvoyé moins de lignes que ce que le développeur attendait.

Ce que cela signifie pour les marchands

Une boutique qui supprime silencieusement les SKU en rupture de stock crée plusieurs problèmes :

  • Les composants front-end reçoivent des entrées manquantes, produisant des étiquettes vides ou des prix erronés.
  • Le débogage devient plus difficile car le symptôme — la disparition de produits — ne génère aucun avertissement.

Comme la plupart des tests automatisés utilisent des fixtures de produits en stock, le bug reste souvent caché jusqu'à ce que le site fonctionne avec un inventaire réel.

Comment conserver la rapidité sans masquer l'inventaire

  1. Ignorer le filtre de stock par défaut – Supprimez explicitement le filtre de la collection si vous avez besoin de chaque produit, quelle que soit sa disponibilité. Magento propose des méthodes pour désactiver ou remplacer le plugin de stock par requête.
  2. Utiliser le repository lorsque la précision est cruciale – Le repository garantit que chaque ID de produit demandé est renvoyé, même s'il est en rupture de stock. Mettez les résultats en cache ou ne chargez que les ID dont vous avez besoin pour limiter le nombre de requêtes supplémentaires.
  3. Employer un resource model ou du SQL brut – Interrogez directement la table des produits pour obtenir les attributs requis. Cela contourne tous les plugins de collection et vous donne un contrôle total sur les lignes incluses.

Vitesse contre exactitude

Remplacer une boucle N+1 gourmande par une seule requête de collection semble naturel ; la baisse de latence est tangible. Pourtant, une requête plus rapide qui renvoie un mauvais ensemble de produits est un défaut, pas une optimisation. Les développeurs doivent mettre en balance la vitesse pure et le risque d'afficher un catalogue incomplet.

Points de vigilance pour la suite

  • Dérive de configuration – Vérifiez que le flag Display Out of Stock Products correspond au comportement attendu de tout code de collection personnalisé.
  • Effets de bord des plugins – D'autres modules peuvent ajouter leurs propres filtres aux collections. Examinez la pile de plugins (plugin stack) chaque fois que vous modifiez vos stratégies de requête.

La leçon est claire : résoudre un problème N+1 avec une collection n'est bénéfique que si vous auditez également les filtres par défaut de cette collection. Ignorer le filtre de stock intégré de Magento peut élaguer silencieusement votre catalogue, transformant un gain de performance en une perte de revenus.