Conditional asset loading deep dive: how we cut 40% of CSS payload on a WooCommerce store.

A walkthrough of identifying and eliminating unnecessary CSS from a high-traffic e-commerce site using a combination of plugins and custom logic.

8 min read Monday Digital Lab
40% CSS payload reduction achieved without removing any active features

The Problem With WooCommerce CSS

WooCommerce registers and enqueues a significant volume of stylesheets globally — on every page, regardless of whether any WooCommerce elements are present. A homepage, blog post, or contact page on a WooCommerce site loads the full WooCommerce component library, cart styles, checkout styles, and often the payment gateway CSS, none of which are rendered on that page.

The same problem exists with most multipurpose themes: they bundle hundreds of component styles in a single stylesheet and deliver all of them on every page load. Combined with WooCommerce, a typical store was delivering 420 KB of unminified CSS to a product listing page that needed roughly 180 KB of it.

Identifying the Bloat

We audited using two complementary tools. Chrome's Coverage panel (DevTools → More Tools → Coverage) shows unused CSS byte-for-byte per page. We ran it across eight representative page types: home, category, product, cart, checkout, account, blog post, and contact.

The Coverage panel identified which stylesheet handles were loading but contributing zero used rules. We cross-referenced with the WordPress handles enqueued by wp_print_styles to map stylesheet handles to their registering plugins or theme functions.

Coverage auditing

Run the Coverage panel with the cache disabled. Reload the page, then click the reload button inside the Coverage panel to capture a fresh profile. Sort by "Unused Bytes" descending — your highest-priority targets will be at the top.

The Dequeue Approach

WordPress's wp_dequeue_style() allows any registered stylesheet to be removed before output. The pattern is: hook into wp_enqueue_scripts at a late priority, check the current page context, and dequeue stylesheets that serve no purpose on that page type.

We did not use a plugin for this. Conditional asset loading logic is tightly coupled to the site's specific content architecture — a plugin that tries to generalise it either misses edge cases or requires so much configuration that writing the code directly is faster and more reliable.

Implementation

The implementation lived in a site-specific plugin — not the theme — so it survived theme updates. We created a conditional map: an array of stylesheet handles keyed by the page conditions under which they should be removed.

PHP — conditional dequeue in a site plugin
add_action( 'wp_enqueue_scripts', 'mdjhd_conditional_dequeue', 99 );

function mdjhd_conditional_dequeue(): void {
    // Remove WooCommerce styles on non-WooCommerce pages
    if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() && ! is_account_page() ) {
        wp_dequeue_style( 'woocommerce-layout' );
        wp_dequeue_style( 'woocommerce-smallscreen' );
        wp_dequeue_style( 'woocommerce-general' );
        wp_dequeue_style( 'wc-blocks-style' );
    }

    // Remove payment gateway styles everywhere except checkout
    if ( ! is_checkout() ) {
        wp_dequeue_style( 'stripe-styles' );
        wp_dequeue_style( 'wc-gateway-paypal-styles' );
    }

    // Remove Dashicons on the frontend (only needed in wp-admin)
    if ( ! is_user_logged_in() ) {
        wp_dequeue_style( 'dashicons' );
    }
}

Measured Results

After deploying the conditional dequeue logic across all page types, we ran a before/after comparison using WebPageTest (Dulles, Virginia, cable connection, first view).

  • Homepage CSS payload: 418 KB → 201 KB (52% reduction)
  • Blog post CSS payload: 418 KB → 198 KB (53% reduction)
  • Product page CSS payload: 418 KB → 312 KB (25% reduction — more WooCommerce CSS legitimately needed)
  • Checkout CSS payload: 418 KB → 418 KB (no change — all styles needed)
  • Aggregate across all page types: 40% average reduction
LCP impact

Homepage LCP improved from 2.8 s to 2.1 s on the throttled mobile profile. The CSS reduction was the primary contributing factor — no other changes were made between the test runs.

Keeping It Maintainable

The biggest risk with conditional dequeue logic is that it breaks silently when plugin updates change stylesheet handles. We mitigated this with two practices.

  • Each dequeued handle is commented with the registering plugin name and version at the time of writing. When a plugin updates, the comment surfaces the dequeue logic for review.
  • Our staging smoke-check list includes a CSS rendering check on the checkout page after every WooCommerce or payment plugin update — the pages where unintended dequeuing would be most visible and commercially costly.

Ready to Start?

Your next production-ready tool starts here.

Lightweight. Privacy-First. Built from real production experience. Pick a plugin and ship it today.

Back to top