Key Takeaways
- WooCommerce sites are 2–3× harder to optimise than standard WordPress because of dynamic content, database complexity, and uncacheable pages
- Product pages fail Core Web Vitals more than any other page type — heavy images, variable product JavaScript, and review widgets are the main culprits
- Checkout and cart pages can’t be page-cached — they need server-level optimisation (Redis, PHP tuning, database indexing)
- Every 100ms of checkout delay reduces conversions by 1.5–2% — speed directly equals revenue for ecommerce
- The WooCommerce-specific fixes in this guide typically improve scores by 40–60 points and reduce load times by 3–5 seconds
Why WooCommerce is different
If you’ve followed our WordPress speed optimisation guide, you already know the fundamentals — server configuration, caching, image optimisation, asset management. But WooCommerce throws a spanner in the works. Most of those standard fixes don’t apply cleanly to an online store, and some actively break things if you apply them blindly.
WooCommerce sites face a fundamentally different performance challenge. Standard WordPress pages are largely static — a blog post is the same HTML for every visitor, making it trivially cacheable. WooCommerce pages are dynamic. A product page shows different prices by currency, different stock status in real time, different variation selections. The cart is unique to every visitor. The checkout page can’t be cached at all without breaking payment processing.
The database layer is dramatically more complex. A standard WordPress site with 500 posts might have 10,000 rows in wp_postmeta. A WooCommerce store with 500 products routinely has 200,000+ rows — every product attribute, every variation, every price point, every stock level is a separate meta row. Add order history, customer data, and coupon rules, and your database is 10–50× the size of a standard site with the same number of “pages.”
Then there’s the JavaScript problem. WooCommerce loads cart fragment AJAX on every single page — even your blog posts — to keep the mini-cart widget updated. Variable products load complex variation selection scripts. Payment gateways inject their own JavaScript on every page “just in case.” The result is a JavaScript payload that dwarfs what a standard WordPress site loads.
This guide covers every layer of WooCommerce-specific optimisation. If your store scores below 50 on PageSpeed Insights — which most do — the fixes here will typically deliver a 40–60 point improvement. For a broader understanding of how these metrics affect your search visibility, see our Core Web Vitals guide.
The WooCommerce speed stack
WooCommerce performance breaks down into six interconnected layers. Each one needs WooCommerce-specific attention — generic WordPress advice misses the nuances at every level.

Layer 1: Hosting. WooCommerce needs 2–3× the server resources of a standard WordPress site. PHP workers, Redis object caching, NVMe storage, and MySQL tuning all matter more when every uncacheable page hits the database. We cover this in detail in our WooCommerce hosting guide.
Layer 2: Database. The wp_postmeta table is the bottleneck. Every product query joins against this massive table. Proper indexing, regular cleanup of expired transients and orphan meta, and separating WooCommerce lookup tables can cut query times by 60–80%.
Layer 3: Caching. This is where WooCommerce gets tricky. You can page-cache product and shop pages, but you absolutely cannot cache cart, checkout, or my-account pages. Cart fragments AJAX creates a dynamic element on every cached page. Getting caching right means understanding exactly what’s cacheable and what isn’t — and using Redis object caching for everything else.
Layer 4: Images. A store with 500 products and 5 images each has 2,500 source images. WooCommerce generates 6–8 thumbnail sizes per image by default. That’s 15,000–20,000 image files — and most are never used. Smart WooCommerce image optimisation means reducing thumbnail sizes, converting to WebP, implementing proper srcset, and strategic lazy loading.
Layer 5: Frontend assets. WooCommerce, its extensions, and your theme collectively load dozens of CSS and JavaScript files. Payment gateways add 200–500KB of JavaScript. Cart fragment scripts run everywhere. Review widgets, zoom functionality, and variation selectors each add their weight. Auditing plugin performance and conditionally loading assets is essential.
Layer 6: Third-party scripts. Analytics, marketing pixels, chat widgets, social proof notifications, retargeting pixels — ecommerce sites accumulate third-party scripts like no other category. Each one adds DNS lookups, SSL handshakes, and main thread blocking time.
Product pages — the most visited, most bloated page type
Product pages are where most WooCommerce performance problems live. They’re the most visited page type in any store and typically the slowest. A default WooCommerce product page with a gallery, variations, reviews, related products, and cross-sells routinely weighs 3–5MB.
The product image gallery is usually the biggest offender. WooCommerce’s default gallery loads three JavaScript libraries — Flexslider for the gallery, Zoom for the hover effect, and PhotoSwipe for the lightbox. That’s 150KB of JavaScript most visitors never trigger. The gallery images themselves are often served at full resolution regardless of screen size.
Variable products add another layer. The variation selection scripts parse a JSON payload containing every possible combination of attributes and their associated prices, stock levels, and images. For a product with 3 attributes and 10 options each, that’s potentially 1,000 combinations in the JavaScript payload. This blocks the main thread and directly degrades INP scores.
Related products and cross-sell widgets generate 4–8 additional database queries per page load. Each query fetches full product data — not just titles and thumbnails. On a site with complex product relationships, these queries can add 200–500ms to page generation time.
Our product page speed guide covers every fix — from image gallery optimisation to variable product JavaScript reduction to review system lazy loading.
Checkout and cart — the uncacheable reality
Checkout speed directly equals revenue. Every 100ms of checkout delay reduces conversions by 1.5–2%. With an average order value of £50 and 1,000 monthly transactions, a 500ms slowdown costs roughly £375–500 per month in lost revenue. Speed pays for itself.
The fundamental challenge is that cart and checkout pages cannot be page-cached. Every visitor has a unique cart, unique session, unique payment state. Each page load hits the full WordPress and WooCommerce stack — PHP execution, database queries, session retrieval, payment gateway initialisation.
Cart fragments are the biggest hidden performance tax. WooCommerce’s wc-ajax=get_refreshed_fragments AJAX call runs on every single page of your site — not just cart and checkout. It updates the mini-cart widget in your header. On a cached page that would otherwise load in 200ms, this AJAX call adds 400–800ms by bootstrapping the entire WordPress stack server-side just to return a cart count.
Payment gateway scripts compound the problem. Stripe, PayPal, and Square each load 200–500KB of JavaScript. By default, most gateway plugins load these scripts on every page. Loading them only on the checkout page is one of the highest-impact single fixes for any WooCommerce store.
We’ve written an entire guide on how to speed up WooCommerce checkout covering cart fragments, payment gateways, field optimisation, and server configuration.
The database reality
WooCommerce’s database architecture is where standard WordPress optimisation advice falls short. The wp_postmeta table — already the performance bottleneck on standard WordPress — becomes enormous on WooCommerce sites.
Every product attribute is a meta row. Every variation is a meta row. Every price, every stock level, every SKU, every weight, every dimension — all separate rows in wp_postmeta. A single variable product with 20 variations can generate 200+ rows in this one table.
The problem compounds with WooCommerce extensions. Every shipping method stores rates in meta. Every payment gateway stores transaction data. Every SEO plugin adds product-specific meta. Every review plugin adds review meta. I’ve audited stores with 500 products and 800,000 rows in wp_postmeta.
WooCommerce 8.x introduced High-Performance Order Storage (HPOS), which moves order data to dedicated wp_wc_orders tables. This helps enormously — but only if you’ve enabled it and migrated existing orders. Many stores are still on the legacy post-based storage.
The autoloaded options are another hidden problem. WooCommerce extensions love storing configuration in wp_options with autoload = yes. I’ve seen stores where autoloaded options total 5–10MB, all loaded into memory on every single page request. Our database optimisation guide covers the general WordPress fixes, but WooCommerce stores need additional attention to product meta indexing and HPOS migration.
Images at scale
Image optimisation on a WooCommerce store is a different beast than on a standard WordPress site. You’re not dealing with a few blog post images — you’re managing a product catalogue of hundreds or thousands of images, each needing multiple sizes, with new products added regularly.
WooCommerce registers 6–8 image sizes by default: the single product image, gallery thumbnail, cart thumbnail, catalogue thumbnail, plus any sizes your theme adds. With 500 products and 5 images each, that’s 2,500 source images generating 15,000–20,000 thumbnails. Many of those thumbnail sizes are never displayed anywhere on your site.
The first step is auditing which thumbnail sizes are actually used and removing the rest. Then converting to WebP (with JPEG fallback for older browsers) typically reduces total image payload by 25–35%. Implementing proper srcset and sizes attributes ensures mobile users aren’t downloading desktop-sized images.
The critical distinction is the main product image — the first gallery image visible above the fold. This is almost always the LCP element on product pages. It must not be lazy loaded. It needs fetchpriority="high" and ideally a preload hint. Every other gallery image should be lazy loaded. Our WooCommerce image optimisation guide walks through the entire process including bulk processing existing catalogues.
The plugin tax
The average WooCommerce store runs 30–40 plugins. That’s not necessarily bad — ecommerce genuinely requires more functionality than a blog. Payment gateways, shipping calculators, tax compliance, inventory management, email marketing, analytics, reviews, SEO — each serves a real purpose.
The problem is cumulative. Each plugin adds database queries on every page load, CSS files, JavaScript files, and AJAX handlers. When 35 plugins each add “just” 50ms to page generation time, you’ve added 1.75 seconds before the browser even starts rendering.
Payment gateway plugins are consistently the worst offenders. Stripe’s JavaScript library, PayPal’s SDK, Square’s payment form — each loads 200–500KB of JavaScript. By default, most load on every page. There’s no reason for Stripe’s JavaScript to load on your blog or product pages. Conditional loading — restricting these scripts to the checkout page — is one of the single highest-impact fixes.
We cover the complete plugin audit process in our WooCommerce plugin performance guide, including how to identify the worst offenders with Query Monitor and replace heavy plugins with lightweight alternatives.
Hosting that handles WooCommerce
Shared hosting fails WooCommerce stores above a modest threshold — roughly 50 products and 500 daily visitors. The reasons are specific to WooCommerce’s architecture.
PHP workers are the bottleneck during checkout. Each concurrent checkout session needs its own PHP worker. Shared hosts typically offer 2–4 workers. If four customers hit checkout simultaneously, the fifth one waits. During a sale event with 50 concurrent shoppers, the queue causes timeouts, abandoned carts, and lost revenue.
Redis object caching is essential for WooCommerce because it caches the database queries that run on every uncacheable page. When a visitor loads the cart page, WordPress executes 50–100 database queries for product data, pricing, shipping rates, and tax calculations. Redis caches these query results in memory, serving subsequent requests 10–100× faster than MySQL.
Managed WooCommerce hosts — Cloudways, Kinsta, WP Engine, Nexcess — outperform generic WordPress hosting by 40–60% on TTFB for dynamic pages. They pre-configure PHP, MySQL, and caching for WooCommerce’s specific needs. Whether the premium is worth it depends on your revenue — if your store makes more than £5,000/month, faster hosting pays for itself in conversion improvements. Our WooCommerce hosting comparison covers the specifics with honest benchmarks.
Why is my WooCommerce site so slow?
WooCommerce sites are slow because they face challenges standard WordPress sites don’t: uncacheable cart and checkout pages, massive database tables from product metadata, cart fragment AJAX calls on every page, heavy payment gateway JavaScript, and product image galleries. Most WooCommerce stores need server-level optimisation (Redis, PHP tuning), database-specific fixes (indexing, HPOS migration), and frontend work (conditional script loading, image optimisation) to achieve fast load times.
What is a good page speed score for WooCommerce?
A well-optimised WooCommerce store should score 80–95 on PageSpeed Insights for product and shop pages, and 70–85 for cart and checkout pages (which are harder to optimise due to being uncacheable). Most WooCommerce stores score between 15–40 out of the box. If your store scores below 50, there are significant gains available. The more meaningful metric is actual load time — product pages should load in under 2 seconds on mobile, and checkout pages in under 3 seconds.
Does WooCommerce slow down WordPress?
Yes. WooCommerce adds significant overhead to WordPress even on non-shop pages. The biggest offender is cart fragments — an AJAX call that runs on every page load to update the mini-cart widget. This adds 400–800ms to every page. WooCommerce also loads its stylesheets and scripts globally, adds database queries for session management, and increases the autoloaded options payload. Disabling cart fragments on non-shop pages and conditionally loading WooCommerce assets are the most impactful fixes.
How do I speed up WooCommerce without losing functionality?
The key is conditional loading, not removal. Instead of removing payment gateway plugins, only load their JavaScript on the checkout page. Instead of disabling cart fragments entirely, disable them on non-shop pages. Instead of removing related products, limit them to 4 and cache the queries. Instead of removing reviews, lazy load them below the fold. These approaches maintain all functionality while dramatically reducing the performance impact on pages where the functionality isn’t needed.
Is WooCommerce or Shopify faster?
Out of the box, Shopify is faster because it’s a managed platform with built-in CDN, optimised infrastructure, and limited customisation scope. However, a properly optimised WooCommerce store can match or beat Shopify’s performance. The advantage of WooCommerce is complete control over server configuration, caching, database optimisation, and code — the same flexibility that causes performance problems when not properly managed also allows expert-level optimisation that Shopify’s closed platform prevents.
Slow WooCommerce store?
Get your free WooCommerce speed audit
Our free audit identifies exactly what’s slowing your WooCommerce store — product pages, checkout, database, hosting, plugins — with specific fixes and expected impact for each issue.