Remove Unused CSS Per Page in WordPress: The Only Approach That Works

February 1, 202610 min read

Last fall I was working on a 340-page WooCommerce site that had been through three different agencies. Each one had layered on plugins, swapped themes, and left behind a graveyard of CSS that no one could untangle. The client wanted one thing: make it fast. So I did what every guide says to do. I ran a site-wide tool to remove unused CSS. It worked beautifully for about 36 hours.

The Phone Call That Changed My Approach

The client called on a Tuesday morning. Checkout was broken. The payment button had lost its styling. The order summary table was unformatted plain text. Customers were abandoning carts because the page looked like it was built in 1997.

What happened was straightforward once I dug in. The tool I used to remove unused CSS per page had actually removed it globally. It crawled the site, found selectors that appeared unused across the majority of pages, and stripped them out. The checkout page used CSS selectors that existed on exactly one page out of 340. The tool saw those selectors as unused because 339 other pages did not need them. It removed them from everywhere, including the one page that did.

This is the core problem nobody talks about. Unused CSS is not a site level concept. It is a per page concept. What is unused on your homepage is critical on your checkout. What is unused on your blog is essential on your product pages. Any approach that treats CSS removal as a global operation will eventually break something.

Why Per-Page CSS Optimization Is the Only Approach That Works

Per page CSS optimization means analyzing each individual URL and generating a stylesheet that contains only the CSS rules that page actually uses. Not a site-wide average. Not a "most pages need this" heuristic. A precise, page-specific stylesheet.

On that same WooCommerce site, once I switched to a per page approach, the results told the whole story. The homepage went from 380 KB of CSS down to 42 KB. Product pages dropped from 380 KB to 67 KB. The checkout page, the one that had broken under the global approach, went from 380 KB to 91 KB. Every page got exactly what it needed and nothing it did not.

The checkout loaded more CSS than the homepage because it genuinely needed more CSS. Payment forms, order tables, coupon fields, trust badges. Those selectors were real and necessary. A per page approach kept them. A global approach had destroyed them.

What Global CSS Removal Actually Does

Most tools that advertise WordPress RUCSS (Remove Unused CSS) work at the site level. They crawl a sample of your pages, build a list of CSS selectors that appear to be in use, and generate one optimized stylesheet for the whole site. Some are smarter than others, but the fundamental approach has a fatal flaw.

Your site is not one page. It is dozens or hundreds of pages with different layouts, different functionality, and different CSS requirements. A contact form page needs form styles. A gallery page needs lightbox styles. A pricing page needs table and toggle styles. A blog post needs typography and code block styles. None of these pages need each other's CSS.

When a tool removes CSS globally, it has to make a choice. Keep a selector because some pages use it, or remove it because most pages do not. Either way, you lose. Keep everything that any page uses and you are barely reducing CSS at all. Remove things that only a few pages use and those pages break.

I have seen this play out across dozens of client sites. The breakage is never obvious. It is a misaligned button on one page. A missing hover state on the mobile menu of a specific template. A form label that lost its font weight. You do not notice until a customer does. Or worse, until your conversion rate drops and you cannot figure out why.

The Font Weight Problem Nobody Mentions

CSS tree shaking on WordPress is not just about layout selectors. One agency client came to me with a portfolio theme that loaded 22 Google Font weights globally. Every page, every visit, 22 font files downloaded and parsed by the browser. The total font payload alone was over 600 KB.

When I ran a per page analysis, the homepage only used 3 of those 22 weights. Interior pages used between 2 and 5, depending on the template. The theme registered all 22 because different templates used different combinations, and the theme author had no way to predict which weights each page would need. So they loaded everything everywhere.

Global CSS removal would not catch this. Font declarations live in @font-face rules, and most CSS purging tools do not trace which font-weight values are actually referenced on a given page. Per page optimization can. It looks at what each page renders, identifies which font weights are actually called, and only loads those. On that portfolio site, the homepage font payload dropped from 600 KB to under 80 KB.

Common Mistakes With WordPress Unused CSS Removal

The first mistake is treating CSS optimization as a one time task. Your site changes. You add pages, update plugins, change templates. Each change can introduce new CSS dependencies. If you removed unused CSS six months ago and have not re-analyzed since, you are either shipping broken styles or bloated styles. Probably both.

The second mistake is trusting visual regression testing to catch everything. "I removed the CSS and the site looks fine" is not validation. Did you check every page? Every responsive breakpoint? Every interactive state? Hover, focus, active, visited? Did you test the print stylesheet? The WooCommerce email templates that inherit site CSS? I once found broken styling on a client's 404 page that had been wrong for four months because nobody ever tested it.

The third mistake is combining CSS removal with file concatenation. Some plugins merge all CSS files into one, then try to remove unused rules from the merged file. This creates a single point of failure. If the parser misidentifies one selector, the damage cascades across every page that depends on that combined file. Per page optimization avoids this entirely because each page gets its own independent stylesheet.

The fourth mistake is ignoring JavaScript-dependent CSS. Many WordPress sites use JavaScript to toggle classes, show modals, open menus, or reveal content. The CSS for those states is technically "unused" when the page first loads because JavaScript has not triggered the interaction yet. A naive CSS removal tool strips those styles. Then a visitor clicks the menu button and nothing happens. Per page CSS optimization needs to account for dynamic states, not just the initial render.

The DIY Trap

I have tried doing this manually. You can use Chrome DevTools Coverage report to see which CSS rules fire on a given page. You can copy the used CSS, create a custom stylesheet, and enqueue it conditionally. It works. On one page. Then you have 49 more pages to do.

Multiply that by every plugin update, theme change, and content addition. The manual approach is not just tedious. It is unsustainable. I maintained custom per page stylesheets for a client with 30 pages for about six months before I accepted that it was a losing battle. A single WooCommerce update invalidated a third of my carefully curated stylesheets because the plugin changed its class naming conventions.

The time cost is real. Auditing one page takes 15 to 30 minutes if you are thorough. Testing takes another 15 minutes across devices. A 50-page site is 25 to 40 hours of work. Then you do it again every quarter. That is a hundred hours a year maintaining something that should be automated.

Per-Page CSS Optimization, Automated

BoostPro analyzes each page individually and generates page-specific optimized CSS. No global removal. No broken checkout pages. Each URL gets exactly the CSS it needs, and the optimization stays current as your site changes.

Get BoostPro

What the Numbers Actually Look Like

After working on per page CSS optimization across a few dozen WordPress sites, the patterns are remarkably consistent. The average WordPress site ships 300 to 500 KB of CSS on every page. After per page optimization, homepages typically land between 30 and 60 KB. Interior content pages between 20 and 50 KB. WooCommerce product pages between 50 and 80 KB. Checkout pages between 70 and 110 KB.

That is an 80 to 90% reduction on most pages. Not through compression or minification, which shaves off 10 to 15% at best. Through elimination of CSS that the page never uses. The remaining CSS is the same code, just without the 85% that was dead weight.

The performance impact is immediate and measurable. CSS is render blocking. The browser will not paint a single pixel until every stylesheet in the document head has been downloaded and parsed. When you remove 300 KB of CSS from a page, the browser starts rendering hundreds of milliseconds sooner. On mobile connections, that gap widens to over a second. LCP improves. First Contentful Paint improves. The page does not just test faster in PageSpeed Insights. It feels faster to every visitor.

Frequently Asked Questions

What does "remove unused CSS per page" mean in WordPress?

It means analyzing each individual page on your site and generating a stylesheet containing only the CSS rules that specific page uses. Unlike global CSS removal, which strips selectors site-wide, per page optimization ensures every page keeps exactly the styles it needs. This prevents the breakage that global approaches cause on pages with unique layouts or functionality.

Will removing unused CSS break my WordPress site?

Global CSS removal frequently breaks sites because it strips selectors that some pages need. Per page CSS optimization avoids this by treating each URL independently. The risk comes from the method, not the concept. A tool that analyzes each page individually and accounts for JavaScript-driven states will not break your layout. A tool that removes CSS site-wide almost certainly will, given enough time.

How much CSS is unused on a typical WordPress page?

The average WordPress page loads 300 to 500 KB of CSS but typically uses only 30 to 90 KB depending on page complexity. That means 70 to 90% of the CSS your visitors download on any given page is never applied. This waste directly impacts Core Web Vitals because CSS is render blocking, meaning the browser cannot display content until all CSS is parsed.

Is CSS tree shaking the same as removing unused CSS?

CSS tree shaking is a more precise term borrowed from JavaScript bundling. It means eliminating dead code by tracing which selectors are actually referenced. In practice, CSS tree shaking on WordPress refers to the same outcome: stripping CSS rules a page does not use. The key distinction is whether the analysis happens globally or per page. Only per page tree shaking produces reliable results on WordPress.

Can I remove unused CSS manually in WordPress?

Technically yes, using Chrome DevTools Coverage report. But it requires auditing each page individually, creating custom stylesheets, and re-auditing after every plugin or theme update. For a 50-page site, expect 25 to 40 hours of initial work plus quarterly maintenance. Most site owners find that automated per page optimization pays for itself within the first round of manual work they skip.