WooCommerce Cart Fragments: Stop the AJAX Drag
Author
John CavilCart fragments can slow your store. They fire an AJAX request on every page to update the mini-cart. That extra call hurts TTFB and blocks render work. The fix is simple: limit fragments to where you need them, or delay them until the user interacts—without breaking checkout.
Works great on any host. On Pofii’s Pofii-Tuned LiteSpeed, pair this with LSCache ESI for a fast, safe setup.
What cart fragments are (and why they slow things)
Cart fragments are a WooCommerce script (wc-cart-fragments) that refreshes mini-cart HTML via wc-ajax=get_refreshed_fragments.
How to see it
- Open DevTools → Network.
- Load any page.
- You’ll see
?wc-ajax=get_refreshed_fragmentssoon after the first paint. - That request runs on every page view by default.
Why it’s a problem
- Extra requests increase TTFB and JS main-thread work.
- On mobile and slower connections, it’s noticeable.
- Many themes don’t even show a dynamic mini-cart. You pay the cost anyway.
Decide your strategy (pick one)
- Disable fragments everywhere except Cart/Checkout.
- Delay fragments until the visitor shows intent (scroll, hover, click).
- Replace fragments with a lightweight counter updated on add-to-cart.
Start with disable except Cart/Checkout. It’s the safest and fastest win.
Fix #1 — Disable fragments sitewide (keep them on Cart/Checkout)
Place this in your theme’s functions.php or a small mu-plugin:
// Disable WooCommerce cart fragments everywhere except cart/checkout
add_action('wp_enqueue_scripts', function () {
if (is_admin()) return;
if (!is_cart() && !is_checkout()) {
wp_dequeue_script('wc-cart-fragments');
wp_deregister_script('wc-cart-fragments');
// Optional: tidy up fragment storage to avoid stale noise
wp_add_inline_script('jquery', "try{sessionStorage.removeItem('wc_fragments');localStorage.removeItem('wc_cart_hash');}catch(e){}");
}
}, 100);
When to use this
- Your header shows a cart icon or static link.
- You don’t need real-time mini-cart content on every page.
- You do need 100% reliable Cart and Checkout pages.
Fix #2 — Delay fragments until user interacts
If your theme needs the mini-cart, load fragments after a small signal—like the first scroll or hover. Keep the default script, but stop it from firing instantly by removing it and loading it on demand.
// Delay loading of wc-cart-fragments until user interacts
add_action('wp_enqueue_scripts', function () {
if (is_admin() || is_cart() || is_checkout()) return;
// Don't load the default script now
wp_dequeue_script('wc-cart-fragments');
wp_deregister_script('wc-cart-fragments');
// Load it after first interaction
$script = <<<JS
(function(){
var loaded=false;
function loadWCCF(){
if(loaded) return; loaded=true;
var s=document.createElement('script');
// WordPress will print the real URL for us via localized param if present; fallback is common handle path
s.src = (window.wc_cart_fragments_params && window.wc_cart_fragments_params.wc_ajax_url)
? window.wc_cart_fragments_params.wc_ajax_url.replace('wc-ajax=%%endpoint%%','') + 'wp-content/plugins/woocommerce/assets/js/frontend/cart-fragments.min.js'
: '/wp-content/plugins/woocommerce/assets/js/frontend/cart-fragments.min.js';
document.head.appendChild(s);
}
['mousemove','touchstart','scroll','keydown'].forEach(function(evt){
window.addEventListener(evt, loadWCCF, {passive:true, once:true});
});
})();
JS;
wp_add_inline_script('jquery', $script);
}, 100);
When to use this
- You want a live mini-cart.
- You still want a fast first paint.
- You’re okay with loading the mini-cart on demand.
Fix #3 — Lightweight counter (no full fragments)
If your header only needs a count, update it on the added_to_cart event. No fragment refresh needed.
HTML (in your header):
<a href="/cart" class="mini-cart-link">
Cart <span class="mini-cart-count">0</span>
</a>
JS (enqueue a tiny script):
(function($){
$(document.body).on('added_to_cart', function(e, fragments, cart_hash){
// If fragments are available, try to read a count; else fall back to +1
var $count = $('.mini-cart-count');
var current = parseInt($count.text(), 10) || 0;
$count.text(current + 1);
});
})(jQuery);
This does not show line items. It keeps the UI snappy and accurate enough for most stores.
Theme, cache, and CDN checks
LiteSpeed Cache (LSCache)
- Keep page cache for anonymous users.
- Exclude
/cart/,/checkout/,/my-account/from cache. - Use ESI for the mini-cart widget if you must show dynamic content in a cached page. See our guide: LiteSpeed Cache safe defaults.
Cloudflare / CDN
- Bypass HTML cache for logged-in users and checkout paths.
- Don’t force “Cache Everything” on pages with cart state.
- Keep Full (strict) SSL to avoid redirect loops.
Object cache (Redis)
- It helps database work, but it won’t fix fragments. Use it alongside the fixes above. See: WordPress Object Cache (Redis).
Images & LCP
- A noisy fragments call often delays your hero image. Make sure the product hero is eager with
fetchpriority="high". See: WooCommerce Image Speed.
Test plan (5 minutes)
- Network tab: load home/category/product; confirm no early
wc-ajax=get_refreshed_fragments(except Cart/Checkout). - Add to cart (AJAX): ensure header count or mini-cart updates based on your chosen fix.
- Cart and Checkout: must work perfectly.
- Repeat view: confirm faster first paint and lower request count.
- Mobile: test on 4G/slow-3G throttling.
Minimal checklist
- Choose a strategy: disable, delay, or counter only
- Keep fragments active on Cart/Checkout
- Exclude Cart/Checkout from page cache
- If needed, use ESI for mini-cart widget
- Validate with DevTools (no early
wc-ajaxcalls) - QA add-to-cart, login, and checkout on mobile/desktop
FAQ
Will disabling fragments break checkout?
No. Cart and checkout do not rely on fragments. Keep fragments enabled only on those pages, and they work as expected.
My theme has a fancy mini-cart. What should I do?
Use Fix #2 (delay) or ESI for that widget. Test on mobile. If it still hurts LCP, consider the counter-only approach.
Do I need a plugin for this?
Not necessarily. The snippets above cover most cases. A lightweight plugin is fine if you prefer toggles.
Why is TTFB still high after changes?
Fragments are one cause. Also check server time, database queries, and image priority. Pair this guide with LSCache and Redis for full speed.
Leave a Comment