Most PageSpeed case studies cheat. They show a near-empty demo theme with a hero image, three products and no real modules, score 100, and call it proof. That proves nothing — any blank PrestaShop scores well. The hard question every store owner actually has is different: can a store that does real work — sliders, mega menu, one-page checkout, live search, blog, popups, loyalty, analytics — still be fast? This post answers that with our own production store, not a sandbox.

mypresta.rocks runs on PrestaShop 9.1 with over 80 active modules, and not the lightweight config-only kind. These are modules that ship their own CSS and JavaScript, hook into the front office, and render visible, interactive elements: animated sliders, a dropdown mega menu, a full one-page checkout, a blog engine with comments and sharing, a live-search widget, social feeds, product galleries, sales popups, countdown timers, a cookie-consent banner, loyalty, analytics dashboards. This is exactly the kind of stack that normally wrecks a PageSpeed score. Ours stays at 99.

This article is the case study: the actual numbers from our live homepage and how the pipeline that produces them is structured. It is deliberately not a generic "make PrestaShop fast" tutorial — for the underlying mechanics we link out to the sibling guides that own each topic properly, so you can go as deep as you need without us repeating ourselves.

The scores, measured by Google — not by us

These come from Google PageSpeed Insights, which runs Lighthouse on Google's own infrastructure against our live homepage. They are not local-tool numbers you can massage; they are what the same report every merchant checks returns right now.

CategoryMobileDesktop
Performance9999
Accessibility9797
Best Practices100100
SEO100100

Performance score is a weighted blend of the Core Web Vitals lab metrics, so the metrics behind the number matter more than the number itself. Here is the full breakdown for both form factors.

MetricMobile (Slow 4G, Moto G Power)Desktop
First Contentful Paint (FCP)1.2s0.3s
Largest Contentful Paint (LCP)1.5s0.9s
Total Blocking Time (TBT)110ms30ms
Cumulative Layout Shift (CLS)00.011
Speed Index (SI)1.4s0.5s

The mobile column is the one that counts. Google indexes mobile-first and throttles the mobile test to Slow 4G on a mid-tier phone, which is brutal compared to the desktop run on a fast connection. A 1.5s LCP and a CLS of exactly 0 under that throttling — with 80+ modules live — is the result we set out to demonstrate. So what does that buy you? A store where the page is usable in roughly a second on a real phone on a real network, which is where most of your traffic and most of your abandonment actually happens.

Why 80+ modules is the whole point

Module count is the variable everyone fears and nobody benchmarks honestly. Every front-office module on PrestaShop tends to add three costs: extra CSS, extra JavaScript, and extra hook execution on every page render. PrestaShop's CCC system (Advanced Parameters → Performance — "Combine, Compress and Cache") reduces and combines the eligible CSS and JS, often into far fewer generated files — exactly how many depends on how the theme and modules register their assets, media types and exclusions — which fixes much of the request-count problem but creates a payload problem: on our store the combined stylesheet was over 850KB before treatment, the overwhelming majority of it rules that never fire on the homepage.

That is the real reason heavy stores feel slow — not "too many modules" as a moral failing, but megabytes of combined CSS/JS that block the first paint while the browser parses rules and scripts the visitor will never trigger. If you want the diagnostic version of this — how to tell which layer is actually hurting you — that is a sibling topic, covered in what actually makes PrestaShop slow and the checking workflow in is your store slow, how to check it. The point here is that we kept all 80+ modules and attacked the payload instead of deleting features.

How the pipeline is built, layer by layer

There is no single switch. The 99 is the sum of a disciplined pipeline that touches the render path at every layer. Below is what each stage does and, more importantly, why it moves the needle — with the deeper theory linked out where a sibling guide owns it.

Critical CSS extraction and async load

Render-blocking CSS is the biggest enemy of a fast first paint: the browser will not paint anything until it has the stylesheet. Inlining the whole 500KB+ file would be worse, not better. Instead we extract the above-the-fold critical CSS for the page and inline only that small slice directly in the HTML; the full combined stylesheet is then loaded asynchronously with the media="print" onload swap pattern, so it downloads in the background without blocking. The browser paints immediately using the inlined critical styles, then upgrades to the full sheet once it arrives. The benefit: the page is visible in about a second instead of waiting on half a megabyte of CSS, and because the critical slice already styles what is on screen, the swap causes zero layout shift.

CSS purging

With 80+ modules the combined CSS carries thousands of selectors that never match anything on a given page. We run PurgeCSS against the real rendered HTML of key page types plus every JavaScript and template file in the theme and modules, so dynamically toggled classes survive. On our store that took the stylesheet from 852KB to 548KB — a 36% cut. Less CSS is less to download on Slow 4G, less to parse on a mid-tier CPU, and a faster, shift-free swap.

JavaScript splitting and deferral

Not all JavaScript needs to run before the page is interactive. We split the CCC JavaScript bundle into two:

  • Sync bundle (~140KB / 41KB gzip): only the core that the page genuinely needs early — jQuery and PrestaShop core scripts.
  • Deferred bundle (~497KB / 111KB gzip): Bootstrap, theme scripts and non-critical module scripts, loaded with the defer attribute so they execute after the document is parsed.

Deferring the heavy bundle keeps it off the main thread during the critical window, which is what pulls Total Blocking Time down to 110ms on mobile and 30ms on desktop. TBT is the metric module-heavy stores fail hardest, because every module's script wants to run at once on load.

Smart, page-aware asset loading

The most wasteful pattern in PrestaShop performance is shipping checkout and payment JavaScript to visitors who are reading the blog. We load context-aware: checkout JavaScript (180KB+ minified) is fully deferred on non-checkout pages, pulled in via requestIdleCallback on the homepage and content pages so it is warm if needed but never competes during first paint, and loaded immediately only on product, cart and checkout pages where it is actually used. Stripe's payment JavaScript is removed entirely from non-checkout pages. So what? A customer landing on a blog post or category never pays the download and execution cost of a checkout they are not at yet.

Image optimization without PHP overhead

Images are usually the LCP element, so they decide the metric that weighs heaviest. Every product and banner image is served in AVIF through Apache content negotiation — the swap to the modern format happens at the web-server layer with zero PHP overhead per request. Our batch converter processed 5,399 images and took total image storage from 994MB to 44MB (95.6% smaller). The mobile hero banner ends up at 25KB, the desktop version at 56KB, both at quality you would not notice was compressed.

One counter-intuitive lesson is worth more than any setting: we preload only the mobile LCP image and nothing else. On Slow 4G at roughly 200KB/s, every extra preload competes with the critical CSS for the same thin pipe. Preloading a web font or the desktop banner actually made our mobile FCP worse — we measured it, reverted it, and that restraint is part of why LCP lands at 1.5s.

Accessibility as a deliberate target, not a side effect

The 97 Accessibility score is engineered, not lucky. It required holding every element to WCAG 2.1 AA contrast (4.5:1 for body text, 3:1 for large text), visible focus indicators on interactive elements, a correct heading hierarchy with ARIA labels, and proper use of a visually-hidden utility so screen readers get content that is hidden from sight. Why a store owner should care: the same discipline that makes a page accessible — honest contrast, no layout jumps, predictable focus — is the discipline that keeps CLS at 0 and keeps real customers from misclicking. Accessibility and conversion pull in the same direction.

What this case study deliberately does not cover

Front-end render optimization is only half of store speed. The other half is what happens on the server before a single byte reaches the browser — database query time, object caching, full-page caching and hosting — and each of those is a topic deep enough to deserve its own guide rather than a paragraph here. Treating them properly elsewhere is also how we avoid telling you the same thing five times across five posts.

How to reproduce this on your own store

If you take the numbers above and try to verify a change on your store, do it the way that survives scrutiny rather than the way that fools you. Before touching anything, run PageSpeed Insights on the page you care about and write down the four lab metrics that drive the score — LCP, TBT, CLS and Speed Index — separately for mobile and desktop, because they move independently. Make one category of change at a time (CSS, then JS, then images), re-test, and keep the change only if the metric it targets actually improved. The preload lesson above is the warning: a change that sounds like an optimization can regress mobile FCP, and you only catch that if you measure before and after rather than trusting the brochure.

One honest caveat on the scores themselves: PageSpeed lab results vary a few points run to run, and they depend on the page tested and current server load. Treat 99 as "consistently excellent," not a fixed constant — what holds steady is the shape of the result, a sub-2-second mobile LCP and near-zero CLS on a fully featured store.

Where the modules come in

The reason this case study exists is that every technique above is not a one-off we hand-built for our own site and kept to ourselves — it is packaged. In the setup we measured for this case study, the Performance Revolution module is the pipeline behind these numbers — the live PageSpeed report on our homepage is the evidence: the critical-CSS extraction and async swap, the CSS purge, the sync/deferred JavaScript split, the page-aware checkout and Stripe deferral, and the AVIF image delivery. So what does that mean for you? You get the front-end optimization that earned this 99 configured from your back office instead of paying a developer to rebuild a render pipeline by hand — and because it works at the asset-pipeline layer rather than forking your theme, it does not break at the next upgrade.

Front-end is half the stack, so we pair it with Instant Redis for server-side object caching — the front-end pipeline makes the page render fast once PHP has produced it, and Redis makes PHP produce it faster. Together they cover both halves of the speed problem this post and its server-side siblings describe.

The takeaway is narrow and honest: a real PrestaShop 9.1 store with 80+ active, front-end-heavy modules can score 99/100 on the same Google test you use to judge your own. It does not require deleting features or a blank demo theme. It requires attacking the asset payload instead of the feature list, measuring every change on the mobile profile that Google actually weighs, and treating the server-side layers — database, full-page cache, Redis, hosting — as the other half of the job, not an afterthought.

Share this post:
David Miller

David Miller

Over a decade of hands-on PrestaShop expertise. David builds high-performance e-commerce modules focused on SEO, checkout optimization, and store management. Passionate about clean code and measurable results.

Enjoyed this article?

Get our latest tips, guides and module updates delivered to your inbox.

Comments

No comments yet. Be the first!

Be the first to ask a question or share useful feedback.

Loading...
Back to top