PrestaShop performance : optimiser gros catalogues et Core Web Vitals

Mesures reproductibles, optimisation SQL et index, cache multi‑niveaux et optimisations front pour rendre PrestaShop rapide sur gros catalogues et améliorer les Core Web Vitals.

Écran d'ordinateur affichant des données pour optimiser PrestaShop.

Table des matières :

  1. Mesure Core Web Vitals et performance PrestaShop : instrumentation reproductible
  2. Gros catalogues : où PrestaShop ralentit vraiment (SQL, index, N+1)
  3. Cache multi-niveaux : OPcache, Redis, Varnish, CDN (et leurs limites)
  4. CWV sur PrestaShop : optimiser LCP, INP, CLS sans casser le thème
  5. Traitements asynchrones, indexation et trafic : éviter que le catalogue écrase le runtime
  6. Plan d’action concret (gros catalogue + CWV) : prioriser sans se mentir

Mesure Core Web Vitals et performance PrestaShop : instrumentation reproductible

Optimiser un gros catalogue PrestaShop « au feeling » revient à déplacer le problème. Commencez par isoler les métriques business (taux de conversion, panier moyen, taux d’ajout au panier, revenue per visitor) des métriques techniques (TTFB, LCP, INP, CLS, p95/p99) et alignez tout le monde sur un protocole unique. L’objectif est bien celui rappelé par Google sur web.dev/vitals : les Core Web Vitals mesurent l’expérience utilisateur réelle (données terrain), pas une simple performance « en labo ». Pour PrestaShop, le piège classique est de confondre lenteur serveur (TTFB) et lourdeur front (LCP/INP) : les deux se traitent, mais avec des leviers différents.

Pour la mesure, combinez Lab + Field :

  • Lab (réplicable, comparable) : Lighthouse (idéalement en CI), WebPageTest, profilage PHP/MySQL, comparaison « avant/après » sur un scénario stable (même page, même device, même conditions réseau).
  • Field (réel, donc prioritaire) : Search Console (rapport CWV) + CrUX si le site est éligible, et idéalement un RUM (Real User Monitoring) intégré à votre observabilité.

Un cadre simple (et souvent suffisant) pour éviter les débats stériles « score Lighthouse vs ressenti » :

Ce que vous voulez piloter Indicateur Où le mesurer Pourquoi c’est utile sur gros catalogue
Vitesse perçue LCP (p75 mobile) Field (RUM/CrUX), Lab (Lighthouse) Images produits lourdes, rendu thème, TTFB masqué
Réactivité INP (p75 mobile) Field (RUM), Lab partiel JS de facettes, carrousels, scripts tiers
Stabilité visuelle CLS (p75) Field + Lab bannières, widgets d’avis, modules paiement/chat
Capacité serveur TTFB (p95/p99) Logs/APM + WebPageTest cache raté, DB saturée, back-office/modules

Repères (utiles pour prioriser sans sur-optimiser) : Google considère généralement comme « bon » LCP ≤ 2,5 s, INP ≤ 200 ms et CLS ≤ 0,1 (au p75). Pour le serveur, un TTFB p95 qui grimpe pendant les pics est un signal d’alerte plus actionnable qu’une moyenne.

Si vous devez cadrer la démarche, partez de la méthode outillée décrite dans l’article interne Audit performance PrestaShop : méthode en 6 étapes reproductibles. Le point important n’est pas la note Lighthouse, mais la distribution (p75 CWV, et p95 TTFB côté serveur) sur les templates clés : catégorie, fiche produit, recherche, panier/checkout. Sur un gros catalogue, ajoutez explicitement deux gabarits souvent oubliés : page marque/fabricant et page « nouveaux produits » (qui déclenchent parfois des tris coûteux).

Côté PrestaShop, utilisez systématiquement un environnement de test proche prod (même PHP, même MySQL/MariaDB, même CDN, même règles Varnish/Redis) et tracez : (1) le nombre de requêtes SQL par page, (2) le temps cumulé SQL, (3) le temps de rendu template (Smarty/Twig), (4) le poids JS/CSS, (5) les appels tiers. Le debug/profiling natif vous aide à objectiver le SQL : Prestashop debug/profiling. Pour la partie MySQL, activez un slow query log (en staging d’abord) et exploitez-le sans pitié : activer le slow query log.

Astuce « terrain » qui évite beaucoup de faux diagnostics : segmentez vos mesures par pays et par device (mobile vs desktop). Si votre marché est majoritairement francophone, un test « mobile 4G » sur un point de présence européen est souvent plus représentatif qu’un desktop fibre en local. Côté Field, vos visiteurs (et Google) ne naviguent pas depuis votre bureau.

Pour CrUX et son écosystème (éligibilité, datasets, API), une doc de référence utile est : CrUX developer docs

Gros catalogues : où PrestaShop ralentit vraiment (SQL, index, N+1)

Avec un catalogue à 50k/200k/500k produits, la plupart des ralentissements viennent de la base : jointures sur *_lang, *_shop, prix spécifiques, stock, navigation à facettes, et surtout requêtes générées en série. Sur PrestaShop 8.1.x et 9.x, une part significative de la charge s’explique encore par des patterns « ORM-like » (même si ce n’est pas un ORM strict) : boucles de chargement d’objets et requêtes N+1 côté modules/thèmes. Gardez en tête ce rappel : un ORM n’est pas gratuit et les N+1 tuent le p95 ; l’article interne ORM : limites, requêtes N+1 et quand préférer le SQL brut est transposable à beaucoup de modules PrestaShop.

Un mini-scenario typique (et très concret) sur gros catalogue :

  • Page catégorie : 48 produits affichés.
  • Le thème appelle un hook « badges produit ».
  • Un module exécute 1 requête par produit pour récupérer une info (ex. label, stock, promo, note).
  • Résultat : +48 requêtes, souvent rapides individuellement… mais catastrophiques en cumulé, surtout quand la DB est déjà chaude.

Ce genre de cas se repère vite en croisant :

  • le compteur de requêtes par page (profiling PrestaShop),
  • le slow log (les requêtes « pas si lentes » mais répétées),
  • et un APM (quand disponible) pour repérer les fonctions qui itèrent.

La correction la plus rentable sur gros catalogue, c’est souvent l’indexation (au sens MySQL) et la réduction du travail fait à la requête. Concrètement : vérifiez les index utilisés via EXPLAIN ANALYZE, chassez les Using temporary / Using filesort, et priorisez les colonnes de filtrage (shop, lang, active, idcategory, dateadd) avec des index composites pertinents. Ne touchez pas « en prod » sans filet : sauvegarde, tests, et rollback.

Checklist très opérationnelle avant de créer/ajuster un index (pour éviter les « index pansement ») :

  • La requête est-elle fréquente (catégorie, recherche, panier), ou rare (back-office ponctuel) ?
  • Filtre-t-elle sur une colonne peu sélective (ex. active=1) ? Si oui, l’ordre des colonnes dans l’index composite compte.
  • L’index va-t-il accélérer sans dégrader les writes (imports, synchro stock) de façon intenable ?
  • Peut-on réduire le coût autrement : limitation du périmètre (shop/lang), dénormalisation ciblée, cache, pré-calcul ?

Pour structurer votre approche côté base, l’article Développeur MySQL : optimiser requêtes, schémas et performances en production donne un cadre solide (index, cardinalité, buffer pool, etc.).

Deux zones « noires » méritent une attention spéciale : recherche et facettes. Le moteur natif de PrestaShop (index + tables ps_search_*) peut devenir un goulet d’étranglement quand vous augmentez langues, attributs et synonymes. Documentez le fonctionnement (pondérations, tables, rebuild) via : index de recherche PrestaShop.

Au-delà d’un certain volume, externaliser la recherche (Elasticsearch/Meilisearch/Solr) n’est pas « du luxe » : c’est une façon de découpler la charge et d’éviter que la recherche ou les facettes ne dégradent le checkout. Un bon indicateur pour trancher : quand la recherche commence à impacter le temps de réponse DB global (lock, saturation CPU, I/O), vous n’êtes plus dans un problème « d’optimisation », mais d’architecture. Pour des choix de techno et de pertinence, voir : moteurs de recherche et l’intégration Meilisearch : intégrer Meilisearch.

Cache multi-niveaux : OPcache, Redis, Varnish, CDN (et leurs limites)

Sur PrestaShop, la performance serveur est principalement une histoire de cache en couches : cache opcode (OPcache), cache applicatif (Symfony/PrestaShop, modules), cache objets (Redis), cache HTTP (Varnish) et cache edge (CDN). Sans OPcache correctement dimensionné, vous payez du CPU pour parser du PHP à chaque requête, ce qui est inacceptable sur trafic réel. Pour des valeurs de référence et une checklist de vérification, utilisez : OPcache paramètres recommandés. Si vous êtes coincé dans un environnement panel, la vérification côté cPanel est documentée ici : vérifier OPcache dans cPanel.

Une façon simple de clarifier « qui fait quoi » (et de ne pas attendre de Redis ce que seul Varnish/CDN peut faire) :

Couche Ce que ça accélère Gain typique Limites fréquentes sur PrestaShop
OPcache exécution PHP CPU serveur mal dimensionné = invalidations, recompile
Redis (objets/sessions) lectures répétitives DB soulagée ne corrige pas une requête SQL lente
Varnish (HTTP) pages anonymes TTFB + stabilité p95 cookies / variations / headers mal gérés
CDN statiques + edge cache latence + débit invalidation, cohérence multi-région

Redis devient rapidement indispensable dès que vous avez : gros catalogue + modules qui multiplient les lectures + sessions/headers coûteux. Mais Redis ne « corrige » pas une requête SQL catastrophique ; il compense. L’implémentation doit être propre : séparation des bases, politique d’éviction cohérente (allkeys-lru vs volatile), surveillance de la fragmentation mémoire, et sécurisation réseau. Pour l’installation et le hardening côté OS : Redis sur Linux : installation & hardening. Pour la config spécifiquement PrestaShop : Redis PrestaShop : config.

Le Full Page Cache (souvent via Varnish) est le levier qui fait réellement chuter le TTFB et stabilise le p95, surtout sur pages catégories/produits anonymes. Attention : PrestaShop core + modules ont une tendance historique à injecter des cookies et à rendre des pages « variées » alors qu’elles pourraient être cacheables, ce qui flingue le hit ratio si vous ne normalisez pas vos headers.

Points de contrôle concrets (très « production-proof ») :

  • Vérifiez le hit ratio (par route) et pas seulement « Varnish est en place ». Un Varnish qui fait 10% de hit est souvent un cache décoratif.
  • Listez les cookies réellement nécessaires en front. Le cookie « marketing » posé dès la première page peut suffire à rendre tout incachable si votre VCL n’est pas stricte.
  • Sur gros catalogue, surveillez la taille des objets en cache (headers + HTML) : certaines pages catégories très longues augmentent les risques de purge coûteuse.

Si vous voulez un point de départ concret (Docker ou non), la démarche VCL et validation du X-Cache est détaillée ici : Configurer Varnish & valider X-Cache. Et pour le volet CDN (cache edge, optimisation images, HTTP/3, shielding), comparez en contexte 2026 : CDN en 2026 : comparatif.

CWV sur PrestaShop : optimiser LCP, INP, CLS sans casser le thème

Les Core Web Vitals à traiter en 2026 sont : LCP (Largest Contentful Paint), INP (Interaction to Next Paint) et CLS (Cumulative Layout Shift). Google a remplacé FID par INP (détails et implications : web.dev/inp). Sur PrestaShop, LCP est souvent une image produit (ou un hero), INP est dominé par JS (carrousels, facettes, scripts tiers), et CLS par des blocs qui apparaissent après coup (bannières, widgets, modules de paiement, avis).

Pour LCP, le travail est mécaniquement front + images. Assurez-vous que l’élément LCP est prévisible : dimensions fixées (attributs width/height ou CSS aspect-ratio), priorité de chargement (fetchpriority="high" sur l’image LCP quand c’est pertinent), et pas de lazy-load sur l’image LCP. Convertissez vos images (WebP/AVIF selon votre pipeline), réduisez la taille des thumbnails et limitez le nombre de variantes.

Deux erreurs courantes sur PrestaShop (surtout avec des thèmes « marketplace ») :

  • Le slider/hero injecte l’image principale tardivement (JS), ce qui retarde le LCP même si l’image est légère.
  • Les images produits sont servies à une résolution trop élevée « au cas où », puis redimensionnées côté CSS : vous payez du réseau inutile sur mobile.

La partie SEO/format image est déjà cadrée ici (utile aussi pour CWV) : SEO & images WebP. Ne sous-estimez pas le serveur : un LCP médiocre est souvent un TTFB médiocre maquillé.

Pour INP, le point faible typique est un thème qui embarque trop de JS synchrones + des modules qui bindent des listeners partout (scroll, resize) sans throttling. L’approche pragmatique : supprimer le JS non essentiel, découper en bundles, charger en defer, et réduire la dépendance à jQuery legacy si votre stack le permet.

Exemples d’actions qui améliorent souvent l’INP sans « réécrire le thème » :

  • Remplacer un carrousel lourd par un composant plus simple (surtout sur mobile) ou le rendre non-bloquant.
  • Déporter le JS des facettes en chargement conditionnel (uniquement sur pages catégories/recherche).
  • Auditer les scripts tiers : chat, heatmaps, A/B testing, retargeting. Sur e-commerce, 3–6 tags peuvent suffire à transformer une interaction (clic filtre / ajout panier) en latence visible.

PrestaShop 9 pousse davantage vers une architecture Symfony/Twig et des contrôleurs services : c’est une opportunité pour rationaliser le rendu et isoler la logique ; mais si vous migrez, faites-le proprement (sinon vous déplacez les coûts). Référence utile : PrestaShop 9 : adapter modules et thèmes.

Pour CLS, c’est rarement « un mystère » : c’est un layout qui bouge parce qu’on n’a pas réservé l’espace. Réservez l’espace pour les bannières, les avis, les blocs cross-sell, et surtout les iframes (paiement, chat, vidéos). Évitez d’injecter des barres promo au-dessus du header après le premier paint. Si vous chargez des polices, utilisez font-display: swap et préchargez uniquement ce qui est réellement critique (sinon vous augmentez le coût réseau et vous n’améliorez rien).

Contexte européen fréquent : les CMP / bandeaux de consentement (RGPD) peuvent provoquer du CLS si leur hauteur varie selon le contenu ou si le bandeau se charge après le rendu initial. La solution n’est pas de « supprimer le bandeau », mais de réserver l’espace (ou d’utiliser un modèle d’affichage qui ne pousse pas le contenu).

En validation, ne vous contentez pas de Lighthouse : vérifiez le CLS en navigation réelle sur mobile (Chrome) et surveillez les régressions via CI (budget de performance) sur les pages stratégiques.

Traitements asynchrones, indexation et trafic : éviter que le catalogue écrase le runtime

Les gros catalogues imposent une discipline sur les jobs : imports, rebuild d’index de recherche, recalcul de prix spécifiques, génération d’images, synchronisation marketplaces. Le core PrestaShop a encore tendance à mélanger certaines responsabilités (runtime vs batch) et beaucoup de modules aggravent ça en déclenchant des traitements lourds sur des hooks synchrones. La règle : tout ce qui n’est pas indispensable à la réponse HTTP doit basculer en asynchrone (cron, queue, worker). Pour inventorier les commandes utiles, appuyez-vous sur : commandes CLI PrestaShop.

Pour éviter que « l’import de 50 000 produits » ne casse la prod, formalisez deux fenêtres :

  • Fenêtre batch (nuit ou creux) : rebuild index recherche, régénération images, gros imports.
  • Fenêtre runtime : uniquement des tâches courtes, idempotentes, et monitorées (ex. synchroniser un stock pour un SKU précis).

Sur gros catalogue, la vraie difficulté n’est pas « lancer des crons », mais d’éviter les effets de bord : montée en charge DB, verrous, purge cache qui invalide tout le site, ou recalcul de prix qui déclenche des cascades. Si un job peut provoquer une purge massive (Varnish/CDN), prévoyez une stratégie : purge par tags (quand possible), purge par lots, ou invalidation progressive.

Sur l’indexation SEO, un catalogue massif crée un deuxième problème : crawl budget et surcharge serveur due aux variations d’URL (tri, pagination, facettes). Même si ce sujet n’est pas « performance serveur » au sens strict, il est directement corrélé au TTFB si Googlebot ou des scrapers attaquent vos endpoints. Travaillez votre sitemap et votre stratégie d’indexation : plan de site & indexation.

Et si votre navigation à facettes vous expose à des floods, la réponse n’est pas uniquement SEO : c’est aussi sécurité/rate limiting (WAF, fail2ban) et contrôle des cookies. Une approche concrète côté protection facettes : bloquer la navigation à facettes via fail2ban.

Enfin, le dimensionnement infra devient non négociable quand le catalogue et le trafic montent : NVMe, buffer pool correctement alloué, séparation éventuelle DB/app, et reverse proxy/load balancer si besoin. Si vous devez absorber des pics (soldes, drops), vous ne tiendrez pas uniquement avec « optimiser le thème ». Travaillez l’architecture (caches, HA, autoscaling) : architecture cloud scalable et la couche reverse proxy (HAProxy) : HAProxy & supervision. Sur incident, ayez une méthodologie 503 et des logs exploitables : diagnostic erreur 503.

Plan d’action concret (gros catalogue + CWV) : prioriser sans se mentir

Commencez par verrouiller les prérequis : PHP supporté (8.2/8.3 selon votre version PrestaShop), OPcache, HTTP/2 ou HTTP/3 côté CDN, et une base correctement dimensionnée. Sans ce socle, vous allez optimiser des symptômes.

Documentez la baseline (sinon vous ne saurez pas prouver les gains) :

  • TTFB p95 (catégorie + produit)
  • LCP p75 mobile (templates clés)
  • INP p75 mobile (catégorie/recherche)
  • CLS p75 (home + produit)
  • Requêtes SQL/page + temps SQL cumulé
  • Hit ratio Varnish/CDN (par route)
  • 10 endpoints les plus lents (p95) côté serveur

Ensuite, attaquez dans l’ordre qui produit des gains mesurables sur gros catalogue : (1) réduire les requêtes SQL (N+1, jointures inutiles, préchargement), (2) ajouter/ajuster des index (sur staging, avec EXPLAIN), (3) activer Redis pour soulager les lectures répétitives, (4) mettre Varnish en frontal et forcer la cacheabilité des pages anonymes, (5) déplacer la recherche vers un moteur dédié si le natif devient instable.

Pour ne pas bricoler, appliquez le raisonnement « mesure → hypothèse → changement → mesure » et gardez un log de changements. Un format simple (et très efficace en équipe) :

Changement Hypothèse KPI attendu Résultat Décision
Désactiver module X sur catégorie réduit N+1 -30% requêtes SQL … garder / remplacer
Ajouter index Y supprime filesort -200ms TTFB p95 … déployer / rollback
Varnish + normalisation cookies +hit ratio +40 pts hit … itérer VCL

Si vous avez besoin d’un cadre pour la dette Symfony et le profilage, le couple Blackfire + refactoring mesurable est bien posé ici : profiling Blackfire & refactoring.

Enfin, finissez par le front CWV (souvent ignoré parce que « ça marche ») : (1) rendre l’image LCP prioritaire, (2) supprimer le JS tiers non critique, (3) imposer des dimensions fixes à tous les médias/iframes, (4) découper CSS (critical CSS + async), (5) bloquer les injections tardives au-dessus de la ligne de flottaison.

Gardez une contrainte claire : ne dégradez pas le checkout. Si vous modifiez le tunnel, testez spécifiquement le module/flow de paiement (ex. one page checkout) et son build : PS OnePageCheckout : prérequis. Et si vous devez trancher sur l’hébergement, faites-le rationnellement (mutualisé vs VPS vs dédié vs cloud managé) : hébergement e-commerce : comparatif.


À lire aussi