Skip to main content
Card class: Non-HeroCategory: Website Performance

At a glance

CSS bytes downloaded but not applied to the rendered page, ranked per stylesheet. Lighthouse’s Coverage analysis identifies which CSS rules never matched any element during the audit; the bytes those rules occupy are “unused CSS”. Brands routinely ship 30-60 percent of their CSS bundle on every page with only 40-70 percent actually applied. Smaller impact than psi_unused_js but easier to fix, tree-shaking unused CSS is largely automatic with modern build tools.
What it countsPer CSS resource: total bytes, used bytes (rules that matched DOM elements), unused bytes (rules that did not match). Lighthouse uses Chrome’s CSS Coverage API to instrument which selectors matched during the audit; the difference between downloaded and matched is “unused”.
Sample typeLab data from a single Lighthouse audit.
Why bundles accumulate unused CSS(1) Theme stylesheets ship rules for every variant: blog templates, multi-language layouts, demo content, alternate skins. (2) Component libraries (Bootstrap, Tailwind base, BC theme styles) ship base rules that may never apply on the merchant’s customised pages. (3) Removed features leave dead rules: a theme update removes a widget but leaves its CSS rules. (4) Per-component CSS bundled site-wide: PDP-specific styles shipped on the homepage; cart-drawer styles shipped on every page including pages without cart action.
Common ecommerce patterns(1) Stencil theme bundle: 130KB total, ~60-80KB unused per page. (2) Klaviyo popup CSS: 30KB total, ~25KB unused on pages without popup. (3) Chat widget CSS: 20KB total, ~15KB unused on most page-loads (chat invisible until hovered). (4) Cookie consent banner CSS: small bytes but present on every page.
Optimisation playbook(1) PurgeCSS or UnusedCSS during build: scan templates, remove unmatched rules. Saves 30-60 percent of theme CSS. (2) Critical CSS inline: extract above-the-fold CSS, inline in HTML, defer the rest. Reduces render-blocking even when the deferred CSS still has unused rules. (3) Per-template CSS bundles: split theme CSS by template; each page loads only its own bundle plus shared core. Modern bundlers handle this via dynamic imports or media attributes. (4) Lazy-load widget CSS: chat widget, popup, cookie banner CSS load when widgets activate, not at page-load.
Smaller impact than unused JSCSS parse + execute is faster than JS parse + execute. The same 100KB of CSS costs 50-150ms on mobile; 100KB of JS costs 200-500ms. Unused CSS is mostly a payload concern (download time, bandwidth); unused JS is also an execution-cost concern. Address unused JS first; tackle unused CSS when JS work is mature.
Currencyn/a, list of byte-savings opportunities.
Time windowT (current state).
Alert triggertop entry > 50KB unused (red), > 25KB unused (amber).
Sentiment keynull
Rolesowner, operations

Calculation

Calculated automatically from your Website Performance (PageSpeed + CrUX) data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.

Worked example

A UK-based BigCommerce fashion store homepage audit, mobile, Wednesday 15 May 26.
RankResourceTotal bytesUsed bytesUnusedCoverage %Recommendation
1stencil-bundle.css (theme)134KB52KB82KB39%PurgeCSS to remove unused theme rules
2klaviyo-popup.css28KB4KB24KB14%Defer load; popup styles unused on most page-loads
3tidio-chat.css22KB6KB16KB27%Defer chat widget CSS to post-load
4web-fonts.css12KB8KB4KB67%Inline critical font-face declarations
5cookie-consent.css8KB6KB2KB75%Acceptable; small bytes
Total CSS shipped204KB76KB128KB37% used
What the ranked list is telling us:
  1. 63 percent of all CSS shipped is unused on this page-load. Smaller proportion than the typical 66 percent unused JS but still a meaningful 128KB of dead bytes downloaded and parsed.
  2. Stencil theme bundle at 82KB unused (rank 1) is the dominant fix. Stencil themes ship rules for many use cases (blog templates, multi-language layouts, alternate skins, demo content) that the merchant doesn’t use. PurgeCSS during build scans the actual theme templates, removes unmatched rules, typically cuts 40-60 percent of theme CSS bundle size.
  3. Klaviyo popup CSS at 24KB unused (rank 2) is loaded synchronously on every page even though the popup fires only on certain triggers. Defer the load to when the popup is about to mount; saves 24KB on most page-loads where the popup never shows.
  4. Tidio chat at 16KB unused (rank 3) has similar pattern, chat widget styles loaded site-wide but only ~27 percent of rules apply on a typical page. Defer to post-load; the chat is invisible until hovered anyway.
  5. Web fonts CSS at 4KB unused (rank 4) is mostly applied. Tightening this is polish; not worth significant effort.
  6. Cookie consent at 2KB unused (rank 5) is acceptable. Skip.
  7. Cumulative impact post-fixes: PurgeCSS theme work (-50KB) + Klaviyo defer (-24KB) + Tidio defer (-16KB) = roughly 90KB reduction. Total CSS bytes drop from 204KB to ~115KB, with most CSS deferred to post-load. Page-weight reduction is meaningful; render-blocking impact is the bigger win because deferred CSS no longer blocks first paint.
The diagnostic flow:
  1. Read top 3 entries. Theme bundle is almost always #1; third-party widget styles next.
  2. Verify in DevTools Coverage tab. Confirms unused-CSS estimates and shows exactly which rules never fired.
  3. Apply build-time tree-shaking (PurgeCSS, UnusedCSS) for first-party CSS.
  4. Defer third-party CSS loads that don’t need to render at first paint.
Rapid-response playbook:
Time horizonAction
First 1 hourIdentify top 3 entries.
First 7 daysConfigure PurgeCSS in build pipeline; tree-shake theme bundle.
First 14 daysDefer third-party widget CSS (Klaviyo, chat).
Re-auditConfirm CSS bytes dropped as expected.

Sibling cards merchants should reference together

CardWhy merchants reach for it
psi_unused_jsSame pattern for JavaScript; higher impact, prioritise first.
psi_render_blockingRender-blocking CSS overlaps with unused CSS; deferring helps both.
psi_total_weightTotal page weight; CSS bytes contribute.
psi_top_opportunities_bytesComposite byte-savings ranking.
psi_top_opportunities_msComposite millisecond-savings ranking.
psi_perf_score_summaryComposite score; CSS work indirectly supports LCP improvement.
crux_lcp_p75LCP improves when render-blocking CSS is deferred.
psi_third_party_costThird-party widgets ship CSS that often dominates the unused-CSS list.

Reconciling against the vendor’s own dashboard

Where to look:
  • PageSpeed Insights, “Reduce unused CSS” opportunity in the Diagnostics section.
  • Chrome DevTools → Coverage tab, line-level visibility of which CSS rules matched DOM elements; the most useful diagnostic tool.
  • PurgeCSS / UnusedCSS / CleanCSS, build-time tools that automate the cleanup.
Why the Vortex IQ unused-CSS may differ from PSI / DevTools:
ReasonDirectionWhat to do
Audit vs interaction. Lighthouse measures unused CSS during synthetic page-load; pages with rich interactivity (hover states, modal opens, dynamic states) may match more rules in real use.Vortex IQ may over-reportUse DevTools Coverage with manual interaction for fairer measurement.
Detection threshold. Lighthouse drops opportunities under a few KB; very small unused-CSS savings don’t appear.Vortex IQ matches LighthouseAdd manual checks for small-CSS patterns if needed.
Cross-connector reconciliation: primarily internal (with psi_render_blocking, psi_total_weight, psi_third_party_cost). Quick rule for support tickets: if a merchant says “I removed unused rules from my CSS but Vortex IQ still shows the same unused bytes”, the most common cause is build/bundle caching, the published bundle still contains the old rules. Verify the deployed CSS file matches the source.

Known limitations / merchant FAQs

Why does my theme have so much unused CSS? Themes ship rules for many use cases. Stencil themes default to broad styling for blog support, multi-language layouts, alternate skins, demo content. Most merchants use a small subset; the rest is dead weight per page. Industry-typical: 30-60 percent unused CSS in untreated theme bundles. Will PurgeCSS break my dynamic content? If configured correctly, no. PurgeCSS scans your templates to identify which selectors are actually used. The risk comes from dynamic content: rules that only apply when JS adds classes at runtime can be incorrectly purged. Configure PurgeCSS’s “safelist” with your dynamic class patterns to prevent this. Should I optimise unused CSS or unused JS first? JS first, almost always. JS has higher byte impact AND higher execution cost on slow devices. Tackle the JS optimisation work mature before turning to CSS; CSS-only optimisation is usually a polish step, not a primary lever. My theme bundle has 130KB of CSS but Coverage tab shows 60KB used. Is the rest really safe to remove? Verify across multiple page types. The 60KB used on the homepage may not be the same 60KB used on PDPs or collections. Run Coverage tab on 5-7 representative pages and union the used rules, that’s the actual “in-use” set. Removing rules outside this set is safe. Will inline critical CSS hurt my performance? Slightly increases HTML size but saves a render-blocking CSS request. For most ecommerce sites the trade-off is positive: 15-25KB of inline critical CSS saves a 100-300ms render-blocking download. The inline cost is parsed before paint anyway, so no net cost. Can Vortex IQ remove unused CSS automatically? Read-only by design. The card identifies what’s unused; build pipeline tools (PurgeCSS, UnusedCSS) handle the actual removal. What about CSS-in-JS frameworks? Different optimisation pattern. CSS-in-JS frameworks (styled-components, Emotion, Tailwind JIT) generate CSS at runtime or build time only for components actually rendered. Unused-CSS is structurally lower for these frameworks; the optimisation work shifts to bundle splitting and tree-shaking the JS that generates the styles.

Tracked live in Vortex IQ Nerve Centre

Unused CSS is one of hundreds of KPI pulses Vortex IQ tracks across Website Performance (PageSpeed + CrUX) and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.