Skip to content

Performance5 min read

How to Speed Up WooCommerce: A Core Web Vitals Playbook

Speed up WooCommerce step by step: faster LCP images, lighter JavaScript for a better INP, safe page caching and a leaner database.

By Hamza Ahmad AslamFull-Stack & WordPress Engineer

A laptop showing an online furniture store on a tidy desk beside a coffee mug and a phone
Photo by Igor Miske on Unsplash (opens in a new tab)
On this page
  1. Know the speed targets first
  2. Step 1: Fix the Largest Contentful Paint
  3. Step 2: Put JavaScript on a diet (this is where INP lives)
  4. Step 3: Cache what can be cached (and nothing else)
  5. Step 4: Clean the database
  6. Step 5: Server basics that still matter
  7. Measure, change one thing, measure again
  8. Frequently asked questions

Short answer: a slow WooCommerce store is usually slow for four reasons: an oversized hero image, too much JavaScript from plugins and tracking tags, pages that can't be cached, and a database bloated with old sessions, logs and autoloaded options. To speed up WooCommerce, fix them in that order, then measure with real-user data rather than a single lab score.

Speed is revenue for a store. Every extra second between "tap" and "product visible" costs you people who never reach the cart. The good news is that the biggest wins are rarely exotic. Below is the order I work through when a WooCommerce site needs to get faster.

Know the speed targets first

Google's Core Web Vitals are measured on real visitors, at the 75th percentile, on mobile and desktop separately.

MetricWhat it measuresGoodPoor
LCP (Largest Contentful Paint)When the main content is visible≤ 2.5 s> 4 s
INP (Interaction to Next Paint)How quickly the page responds to taps and clicks≤ 200 ms> 500 ms
CLS (Cumulative Layout Shift)How much the layout jumps around≤ 0.1> 0.25

Check your field data in the Core Web Vitals report in Search Console or at the top of PageSpeed Insights. Lab tools like Lighthouse are great for debugging, but the field numbers are the ones that count.

Step 1: Fix the Largest Contentful Paint

On most product and home pages, the LCP element is a big image. Make it cheap to download and ask for it early:

  • Serve WebP or AVIF at the size it is actually displayed, with proper srcset sizes.
  • Never lazy-load the LCP image. Lazy-load everything below the fold instead.
  • Give the hero image priority:
<img src="/hero-1200.webp" srcset="/hero-800.webp 800w, /hero-1200.webp 1200w"
     sizes="(min-width: 1024px) 50vw, 100vw" width="1200" height="800"
     fetchpriority="high" alt="Oak dining table in a bright kitchen">
  • Avoid sliders above the fold. They load several large images and a script before anything settles.
  • Preload only the one font file used in the first screen, and use font-display: swap.

Step 2: Put JavaScript on a diet (this is where INP lives)

Most stores don't have a slow server. They have a busy main thread. Open Chrome DevTools, go to the Performance panel, record a tap on "Add to cart" and look for long tasks.

Common culprits and fixes:

  1. Plugins that load everywhere. A form, slider or review plugin often enqueues its scripts on every page. Unload them on pages that don't use them, with your theme's functions.php or an asset manager.
  2. Cart fragments. Recent WooCommerce versions only load the wc-cart-fragments script where a mini-cart needs it. If your theme or a plugin still loads it everywhere, it adds an uncached AJAX request to every page.
  3. Tag managers. Every marketing pixel adds work. Remove tags nobody reads, load the rest after the page is interactive, and consider server-side tagging for the heaviest ones.
  4. Chat widgets and heatmaps. Load them on interaction (for example, when the visitor clicks "Chat") instead of on page load.

Here is a small, safe example that stops a plugin's script loading outside the pages that need it:

add_action( 'wp_enqueue_scripts', function () {
    if ( ! is_page( 'contact' ) ) {
        wp_dequeue_script( 'example-form-plugin' );
        wp_dequeue_style( 'example-form-plugin' );
    }
}, 100 );

Use your plugin's real script handles, which you can find in the page source or with the Query Monitor plugin.

Step 3: Cache what can be cached (and nothing else)

Full-page caching is the biggest win for anonymous visitors, but a store has pages that must never be cached:

  • Cart, checkout and my-account pages
  • Any request carrying WooCommerce's session cookies, such as woocommerce_items_in_cart and wp_woocommerce_session_*

Most good hosts and caching plugins know these rules. Check them anyway, because a cached checkout is a serious bug. On top of page caching, add a persistent object cache (Redis or Memcached) so logged-in shoppers and admin pages stop hammering the database.

Step 4: Clean the database

WooCommerce stores collect clutter quietly. Look at these three places:

  • Autoloaded options. These load on every single request. See how big they are:

    wp option list --autoload=on --format=total_bytes
    

    If that number is in the megabytes, find the largest entries and turn off autoloading for anything left behind by removed plugins.

  • Scheduled actions. WooCommerce's Action Scheduler keeps a log of completed jobs. Clear old completed and failed actions under Tools → Scheduled Actions, and make sure WP-Cron actually runs (a real server cron is more reliable than visitor-triggered cron).

  • Orders storage. Make sure the store uses High-Performance Order Storage (HPOS), which moves orders out of the generic posts tables into dedicated ones. It's the default for new stores. Older stores can switch after checking plugin compatibility under WooCommerce → Settings → Advanced → Features.

Step 5: Server basics that still matter

  • A supported PHP version (8.3 or newer) with OPcache enabled
  • HTTP/2 or HTTP/3 and Brotli or gzip compression
  • A CDN for images, CSS and JS
  • A server close to your customers, or edge caching if they're spread out

Measure, change one thing, measure again

Performance work goes wrong when ten changes land at once. Keep a simple log: what you changed, the Lighthouse or WebPageTest result before and after, and the field data 28 days later. If a change doesn't help, roll it back.

During my time as website developer at Half Price Packaging, the site achieved a 10x boost in performance and a 5x increase in traffic. Results like that come from steady, measured work across all of these layers, not from a single plugin.

Faster sites are also easier to secure, because fewer plugins mean fewer holes. My WordPress hardening checklist pairs well with this guide. If you look after several stores, monitoring them from one place keeps regressions from sneaking back in.


Want a performance review of your store? Tell me about it, or see the services I offer.

Frequently asked questions

Will a caching plugin alone fix a slow store?

It helps anonymous visitors on catalogue pages. It does nothing for cart, checkout or logged-in customers, and it doesn't fix heavy JavaScript. Treat caching as one layer, not the whole fix.

Should I switch themes for speed?

Only if the theme is the bottleneck. Profile first. A lightweight block theme with fewer plugins is usually faster than a page builder stacked with add-ons, but a well-tuned existing theme can be good enough.

How long until Google sees the improvement?

Search Console's Core Web Vitals report uses a rolling 28-day window of real-user data, so give it about four weeks after the fix goes live.

Enjoyed this? Get the next article by email.

Occasional, useful posts. No spam — unsubscribe anytime.