Skip to content

PerformanceUpdated 5 min read

How to speed up WooCommerce: a Core Web Vitals guide

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

Portrait of Hamza Ahmad AslamBy AI & WordPress Developer | Speed Optimization & Site Security

A shopping cart built as a race car in a pit stop; helmeted crew swap heavy engine parts for light ones under three glowing gauges.
Illustration generated with ChatGPT
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: common causes of a slow WooCommerce store include 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, profile the affected journey and prioritize the largest measured delay. Use field data as well as lab traces to verify the result.

Test the routes shoppers use: product pages, search, cart and checkout. The sections below cover different sources of delay. Start with the one your measurements identify.

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 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)

A busy browser main thread can delay interactions even when the server responds quickly. 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 can send an uncached ?wc-ajax=get_refreshed_fragments POST that skips the page cache on the first page view in a tab session, when the stored cart hash no longer matches the cart cookie after a cart change, and when stored fragments expire after 24 hours. Other page views reuse fragments saved in sessionStorage.
  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.

If cart fragments are part of that JavaScript work, check which pages load wc-cart-fragments and whether they need it to keep a cart widget up to date.

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. On WordPress 6.6 and later, autoload can use yes, on, auto-on and auto for values WordPress loads by default, while WP-CLI's --autoload=on filter only counts on and yes. Use the full autoloaded-options measurement method to measure the full set and find the largest entries before changing anything.
  • Scheduled actions. WooCommerce's Action Scheduler keeps a log of completed jobs. Review failed actions before removing their history, agree a retention policy for completed actions, and make sure WP-Cron runs (a system cron is more reliable than visitor-triggered cron).
  • Orders storage. Check whether the store would benefit from 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 from WooCommerce → Settings → Advanced → Features. First check plugin compatibility and enable compatibility mode (order sync). Let the sync finish, then switch, and keep compatibility mode on for a while so you can revert if something breaks.

For order storage, see migrating to WooCommerce High-Performance Order Storage. For background-job buildup, see how to clear a WooCommerce Action Scheduler backlog.

Step 5: Server basics that still matter

  • A PHP version that WordPress and WooCommerce recommend (8.3 or newer), with OPcache enabled. Confirm that your plugins and theme support the target PHP branch on staging before you upgrade.
  • 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. The work there included WordPress admin and theme changes, performance improvements and security cleanup. Those numbers describe that site; another store needs its own baseline.


Want a performance review of your store? Explore my WooCommerce Speed Optimization service or request a store audit.

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.

How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing.

Enjoyed this? Get the next article by email.

Occasional, useful posts. No spam, and you can unsubscribe anytime.

  • Glowing kiosks across a world map hand out copies of a page to queues of tiny travellers while the main library rests, its do-not-copy pages kept inside.Performance

    8 min read

    WordPress CDN caching: cache full pages safely at the edge

    WordPress CDN caching is safe when the CDN stores only anonymous, public HTML and bypasses requests that can vary by user, session, cart, preview, or admin state. Cache static assets broadly, cache full pages selectively, purge changed URLs, and verify the response headers before trusting the policy in production.

    • WordPress
    • Caching
    • Performance
    Read article
  • A faceless traveller walks toward a carriage already lit and open at the platform, while a dark carriage on the next track stays padlocked.Performance

    7 min read

    WordPress speculative loading: faster navigation without breaking a store

    WordPress speculative loading can make page-to-page moves feel faster by asking the browser to fetch likely destinations before a visitor clicks. On a WooCommerce store, keep dynamic and state-changing URLs out of those rules, then verify what Chrome loads before making the behavior more eager.

    • WordPress
    • Performance
    • WooCommerce
    Read article