WooCommerce Cart Fragments: Why They Slow Your Store
WooCommerce cart fragments are the AJAX request (wc-ajax=get_refreshed_fragments) that refreshes your cart count without a page reload, and when it fires site-wide it slows TTFB and add-to-cart. The fix is to load fragments only where the cart shows, not kill them blindly.
WooCommerce cart fragments are the AJAX request (wc-ajax=get_refreshed_fragments) that refreshes your cart count without a page reload, and when it fires site-wide it slows TTFB and add-to-cart. The fix is to load fragments only where the cart shows, not kill them blindly. If I were checking this on a real site, I'd start with the page that earns traffic or money, confirm whether the issue is backend, frontend, content, or layout related, then apply one fix at a time.
What are WooCommerce cart fragments?
WooCommerce cart fragments are an AJAX request that updates your mini-cart count and totals in the background, so the header cart number changes the moment a shopper adds an item without reloading the whole page. The script behind it is cart-fragments.min.js (handle wc-cart-fragments), and the request it fires shows up in your network tab as /?wc-ajax=get_refreshed_fragments.
The reason this exists is caching. When you serve a full-page cache, the header cart count is frozen in that cached HTML, so WooCommerce uses an uncached AJAX call to fetch the live count and swap it in. That's genuinely useful behavior. The problem is where and how often it runs, which I'll get into next. If your whole store feels sluggish for reasons beyond this one request, my WooCommerce speed optimization service walks through the full stack.
One thing most guides skip: fragments aren't one feature, they're two cooperating pieces. There's the JavaScript that runs in the browser, and there's the server-side handler that builds the cart HTML on every call. You can throttle either side, and the smartest fix usually touches both.
Why do cart fragments slow down your store?
Cart fragments slow your store because the request is uncached by design, so every fragment call hits PHP, loads the WooCommerce session, and rebuilds cart HTML from scratch. Caching is what makes WordPress fast, and this is the one request you deliberately can't cache, which means it lands on your origin server's TTFB instead of getting served from cache or a CDN edge.
On a healthy host that single call still costs roughly 300 to 700ms, and on a slow shared host I've watched it balloon past 2 seconds. Perfmatters documents real cases where fragment delays hit 10 seconds on large stores. Now multiply that. If fragments load on your homepage, blog posts, and every landing page, you're paying that uncached PHP tax on pages that have nothing to do with shopping.
Traffic makes it worse fast. Picture a few thousand visitors browsing at once: each page view can spawn its own fragment request, so you stack up thousands of uncached PHP hits in seconds. That's the load pattern behind the 502 and 504 errors stores see during sales, and it's why a slow add-to-cart button often traces straight back to this request fighting for the same PHP workers.
Cart fragments also drag Core Web Vitals indirectly. The request competes for the main thread and network during load, which can push back interactivity and hurt INP (target under 200ms). It's rarely the only culprit, but on a thin homepage it's often the single biggest uncached request firing.
How do you check if fragments fire on every page?
Open your homepage in Chrome, hit F12, go to the Network tab, filter by fragments or wc-ajax, and reload. If you see a get_refreshed_fragments request on a page with no cart widget, fragments are loading where they don't need to. Check the Timing column too, since that tells you exactly how many milliseconds this one call is costing you.
Do this test on three page types: the homepage, a blog post, and a single product page. Fragments belong on shop, cart, and product pages where the mini-cart actually updates. They almost never belong on a contact page or an article. If you spot the request firing on a static page, that's your easy win.
For a deeper read, install Query Monitor and watch the AJAX call's database query count and PHP time when you trigger an add-to-cart. Heavy session tables or a bloated wp_options autoload row will make each fragment call far more expensive than it should be, and that's a database problem hiding behind a fragments symptom. My WooCommerce database optimization guide covers cleaning those up.
If you'd rather not dig through dev tools, run the page through a free WordPress speed audit and look at the waterfall. The fragments request stands out because it's an uncached XHR to your own domain that fires after the page paints.
Should you disable cart fragments or just optimize them?
Disable fragments fully only if your theme doesn't show a live cart count anywhere, otherwise optimize them so they load just on shop, cart, and product pages. Killing the script outright is the fast fix, but it silently breaks the header cart number and the hover mini-cart, and shoppers won't tell you, they'll just bounce when the count looks stuck at zero.
Here's the decision rule I use on client stores. If the site uses a redirect-to-cart flow with no header cart widget, disable fragments everywhere, done. If the header shows a live cart count or a hover mini-cart, don't disable, instead scope fragments to pages that have a cart and leave them off everything else. That keeps the feature where it earns its cost and removes it where it's pure waste.
There's a third option that splits the difference: conditional loading based on the woocommerce_cart_hash cookie. WooCommerce sets that cookie only once a cart has items, so you can load fragments only for shoppers who've actually started a cart, and skip the request entirely for the much larger pool of first-time browsers with empty carts. That's the cleverest balance of the three, and I'll show how it works below.
The wrong move is disabling fragments and calling it done without testing both a logged-out browser and a logged-in account with items already in the cart. That's the mistake I see most, and it's how stores ship a broken cart count for weeks without noticing.
How do you load fragments only on cart and shop pages?
Dequeue the wc-cart-fragments script everywhere except the pages where a cart actually displays, using WooCommerce's own conditional tags. This keeps the live count working on shop, product, and cart pages while removing the uncached request from your homepage, blog, and static pages. Drop this in a code snippet plugin or your child theme's functions file:
add_action( 'wp_enqueue_scripts', function () {
if ( is_woocommerce() || is_cart() || is_checkout() ) {
return; // keep fragments on store pages
}
wp_dequeue_script( 'wc-cart-fragments' );
}, 11 );The priority of 11 matters. WooCommerce enqueues the script at the default priority of 10, so your dequeue has to run after that or it does nothing. This is the single most common reason a copied snippet "doesn't work", and BusinessBloomer flags the same priority detail in their walkthrough.
If your header shows a cart count on every page (a lot of themes do), this approach will freeze that count on non-store pages, which may be fine if shoppers reach the cart through the shop anyway. Test the real flow: add an item from a product page, then browse to the homepage and confirm the experience still makes sense for your store. For a calmer overall checkout path, pair this with my guide to speeding up WooCommerce checkout.
What cache plugin settings handle fragments for you?
Most premium cache plugins already optimize cart fragments, so before you write a single line of code, check whether your stack does it natively. WP Rocket optimizes the get_refreshed_fragments request automatically once WooCommerce is detected, with no toggle to flip, and it ships WooCommerce-aware cache rules that keep cart and checkout pages uncached so you don't serve a stale cart by accident.
On LiteSpeed servers, LiteSpeed Cache handles fragments through its private cache and ESI (edge side includes), which lets it cache the page while leaving the cart block dynamic. That's a more elegant fix than dequeuing, because the page still caches fully and only the cart fragment stays live. FlyingPress and W3 Total Cache offer their own WooCommerce exclusions along the same lines.
Whatever plugin you run, confirm three things in its WooCommerce settings: cart, checkout, and my-account are excluded from full-page cache; the cart fragments request is excluded from caching; and any "delay JavaScript" feature doesn't delay cart-fragments.min.js in a way that breaks the count. If you want the broader picture on dialing in these tools, my cache plugin settings guide covers the WooCommerce-specific rules.
Caching cart responses incorrectly is its own disaster. If a full-page cache ever stores a logged-in cart, shoppers start seeing each other's carts, which is a real bug I've debugged on misconfigured stores. The fragments request is the safety valve that keeps that from happening, so never cache it, and never cache the pages it serves.
Why do sessions and database bloat make fragments worse?
Every fragment call loads the WooCommerce session, so a bloated session table or a heavy autoloaded options row makes each uncached request far slower than the script itself. The JavaScript is tiny. The expense is the server-side work of spinning up a session and querying the cart on each call, and that cost scales with how messy your database is.
WooCommerce stores sessions in the wp_woocommerce_sessions table, and expired sessions pile up if cleanup isn't running. On stores I've audited, that table had tens of thousands of stale rows slowing every cart operation. Clearing expired sessions and keeping the cleanup cron healthy directly speeds up each fragment response, which is why I treat fragments and database health as one job, not two.
Object caching is the bigger lever here. Adding Redis (or Memcached) lets WooCommerce pull session and cart data from memory instead of hammering MySQL on every fragment call, and on a busy store that's often the difference between fragments costing 600ms and costing 150ms. If your host offers Redis, turn it on before you start dequeuing scripts, because it speeds up far more than just fragments.
Don't forget the autoload trap. A swollen wp_options autoload payload (anything over roughly 1MB is a red flag) gets loaded on every single request, fragments included. Trimming it with a tool like database optimization makes every uncached call lighter across the board.
How do you test the cart still works after disabling fragments?
Test as both a logged-out visitor and a logged-in customer, because cart behavior differs between the two and logged-out testing alone hides the most common breakage. Open an incognito window, add a product, and watch the header count and hover mini-cart. Then log in as a real customer account with items already in the cart and repeat. If the count updates correctly in both, your change is safe.
Run this exact checklist after any fragments change: add to cart from a product page, add to cart from the shop archive, hover the mini-cart, proceed to checkout, and remove an item. Each step should reflect the right count instantly or after the expected redirect. Skipping the logged-in test is how stores ship a broken count to their actual buyers while the homepage looks fine.
Then measure, don't guess. Re-run the page through PageSpeed Insights or GTmetrix and confirm the wc-ajax=get_refreshed_fragments request is gone from the waterfall on non-store pages and TTFB dropped (aim for under 0.8s). I keep a before-and-after screenshot of the waterfall on every store I touch, because the missing fragment request is the clearest visual proof the fix landed.
If something feels off, a stuck count or a mini-cart that won't populate usually means the dequeue ran on a page that needed fragments, or the cookie condition is too aggressive. Loosen the condition to include the page in question and retest. When checkout itself feels slow rather than just the cart, my slow WooCommerce checkout guide covers the rest of the chain.
What mistakes break carts when controlling fragments?
The biggest mistake is disabling fragments globally on a theme that shows a live cart count, which freezes that number at whatever it was on page load and makes shoppers think add-to-cart is broken. Always confirm whether your header or mini-cart depends on the live count before you reach for a global disable.
Caching the fragments request is the second trap. The whole point of fragments is that they bypass cache to fetch live cart data, so if a cache plugin or CDN rule accidentally caches get_refreshed_fragments, shoppers see stale or even shared cart contents. Exclude that request explicitly in every layer: page cache, CDN, and any optimization plugin.
Testing only logged-out behavior is the third, and it's sneaky because the homepage looks perfect while logged-in customers hit a broken count. The fourth is using too low a priority on the dequeue hook, so WooCommerce re-adds the script after you remove it and nothing changes. Run the dequeue at priority 11 or higher.
Last one: delaying JavaScript with a performance plugin and accidentally delaying the fragments script itself. "Delay JS until interaction" features are great, but if they catch cart-fragments.min.js, the count won't update until the shopper clicks something. Exclude the fragments handle from delay rules, or scope your delay to non-WooCommerce scripts.
When should you hire a pro instead of fixing fragments yourself?
Hire a specialist when fragments are slow even after you've scoped them correctly, because at that point the real problem is usually hosting, sessions, or database load that a snippet can't fix. If you've dequeued fragments off non-store pages, added Redis, and cleaned the sessions table but add-to-cart still drags, the bottleneck has moved deeper into your stack and needs a proper audit.
It's also worth handing off when your theme or page builder hooks the mini-cart in a custom way, since a careless dequeue can break a builder's cart widget in ways that aren't obvious until checkout. Elementor and Divi stores in particular tend to wire the cart through their own widgets, and that's a place where one wrong snippet costs you sales quietly.
I optimize WooCommerce stores for a living, and fragments are usually one line in a longer report that also covers caching, fonts, images, and the database. If you'd rather have someone diagnose the whole chain and ship the fix safely, here's how I handle WooCommerce speed optimization end to end. You'll get the before-and-after proof, not just a promise.
For a self-serve starting point, run your store through the free speed audit first. It'll tell you whether fragments are even in your top issues, or whether your time is better spent on hosting or images before you touch the cart at all.
My checklist for WooCommerce Cart Fragments
Check if cart fragments load on every page.
Test mini-cart and header cart behavior.
Measure add-to-cart response.
Review cache plugin WooCommerce settings.
Test logged-out and logged-in users.