Back to blog

Fix WooCommerce Cart Fragments Slowing Your Site

WooCommerce cart fragments slow? Here is why the get_refreshed_fragments AJAX call bypasses your cache and the fix that keeps the mini-cart working.

1 views 5 min read
Share

Page load times were fine in GTmetrix, Lighthouse scores looked decent, but every single page load was firing off a chunky AJAX request that showed up nowhere in their usual performance checklist. Turned out to be wc-ajax=get_refreshed_fragments — WooCommerce Cart Fragments — quietly hammering their server on every page, cached or not.

If you've profiled a WooCommerce site in your browser's network tab and spotted a POST request to admin-ajax.php firing on literally every page load, even pages with no cart activity, you've found the same thing. It's one of the most common WooCommerce performance complaints, and almost nobody realizes it's happening until they go looking.

What Cart Fragments Actually Do

WooCommerce ships with a feature that keeps your cart count and mini-cart in sync without a full page reload. Add a product to the cart on one page, navigate to another, and the header cart icon already shows the updated count — no refresh needed. Under the hood, that's wc-cart-fragments.js firing an AJAX call to get_refreshed_fragments on nearly every page load, which runs through WordPress's full bootstrap (themes, plugins, the works) just to re-render a tiny bit of cart markup.

The problem is where that bootstrap happens: admin-ajax.php requests bypass most page caching plugins entirely, since they're treated as dynamic, uncacheable requests by design. So even on a site with a solid caching setup — WP Rocket, LiteSpeed Cache, a CDN in front of everything — this one request slips through uncached, every time, on every page, for every visitor.

Why It's Actually Slow

This is the part that surprised my client. Cart fragments isn't slow because the JavaScript is heavy — it's maybe 2KB minified. It's slow because the AJAX response triggers a full WordPress + WooCommerce load on the server side: your theme's functions.php, every active plugin, WooCommerce's own session handling, all of it, just to return a fragment of HTML that, most of the time, hasn't actually changed.

On a shared host or a small VPS, that server-side cost adds up fast. I measured one client's get_refreshed_fragments response at around 380ms on a typical page — on a site where everything else was loading in under 150ms. Multiply that by every page view from every visitor who isn't actively shopping, and you've got a meaningful chunk of server load going toward a feature most visitors never even interact with.

The Fix Most Tutorials Give You — and Why I'd Push Back on It

Search this problem and you'll find dozens of posts telling you to just dequeue the script outright:

php
add_action( 'wp_enqueue_scripts', 'disable_woocommerce_cart_fragments', 100 );
function disable_woocommerce_cart_fragments() {
wp_dequeue_script( 'wc-cart-fragments' );
}

This works, and it does kill the AJAX call entirely. But here's my actual take: I'd only do this on sites where the mini-cart genuinely doesn't update dynamically anywhere — no AJAX add-to-cart buttons, no header cart count that needs to stay live across page navigation. If your theme or any plugin relies on cart fragments to update the cart icon after an AJAX add-to-cart, ripping it out wholesale breaks that behavior silently. The customer adds something to the cart, the icon doesn't update, and now they're clicking "add to cart" three times because they think it didn't register. I've seen that exact support ticket.

The Fix I Actually Use

Instead of nuking the feature, I disable it only where it has no reason to run — namely, anywhere that isn't a cart-sensitive page — and let it do its job everywhere the cart icon actually needs to stay live:

php
add_action( 'wp_enqueue_scripts', 'conditionally_disable_cart_fragments', 100 );
function conditionally_disable_cart_fragments() {
if ( is_front_page() || is_404() ) {
wp_dequeue_script( 'wc-cart-fragments' );
}
}

That alone usually cuts the AJAX hits by 60-80% depending on your traffic mix, since most of a WooCommerce site's traffic lands on the homepage, blog posts, or landing pages — not product or cart pages. For the pages where fragments still run, you can also shorten the request itself by filtering which fragments actually get calculated:

php
add_filter( 'woocommerce_add_to_cart_fragments', function ( $fragments ) {
unset( $fragments['div.widget_shopping_cart_content'] );
return $fragments;
}, 20 );

Only unset fragments your theme doesn't actually render — check your theme's cart widget markup first, or you'll just break the mini-cart instead of speeding it up.

When You Genuinely Don't Need This at All

If your store has no AJAX add-to-cart anywhere (some minimal or custom themes don't), and your cart icon only needs to update after a full page load, the blanket dequeue from the "most tutorials" section above is actually the right call — don't overthink it in that case. The nuance only matters when something on the site depends on the live update behavior, and the only way to know for sure is to check your theme's add-to-cart buttons for ajax_add_to_cart classes or data attributes before you decide which approach to use.

Either way, test the fix on a staging copy and watch the Network tab while adding a product to the cart from a product listing page. If the cart count updates without a refresh, fragments are still doing something useful on that page. If nothing on the site reacts to it, you've confirmed it's safe to kill entirely.

One more thing worth checking while you're in there: a surprising number of "cart fragments is slow" reports I've seen are actually a slow WC()->cart session lookup caused by database-based sessions on a site with no object cache. If disabling fragments doesn't move your server response time much, the real fix might be adding Redis or Memcached as a persistent object cache instead — fragments was just where the slowness became visible, not where it started.

Start with the conditional dequeue above, confirm nothing broke with a real add-to-cart test, and only go further into fragment filtering or object caching if the server-side cost is still showing up in your profiling after that first change.

Found this useful? Share it.

Share