> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vortexiq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Unused CSS, Website Performance (PageSpeed + CrUX)

> Unused CSS for Website Performance (PageSpeed + CrUX) stores. Tracked live in Vortex IQ Nerve Centre. How to read it, why it matters, and how to act on it.

**Metrics type:** [Supporting Metrics](/nerve-centre/overview#metrics-types-explained)  •  **Category:** [Website Performance](/nerve-centre/connectors#connectors-by-type)

## 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`](/nerve-centre/kpi-cards/website-performance/unused-javascript) but easier to fix, tree-shaking unused CSS is largely automatic with modern build tools.

|                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **What it counts**                    | Per 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 type**                       | **Lab 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 JS**     | CSS 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.                                                                                                                                                                                                                                                                          |
| **Currency**                          | n/a, list of byte-savings opportunities.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **Time window**                       | `T` (current state).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **Alert trigger**                     | `top entry > 50KB unused` (red), `> 25KB unused` (amber).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **Sentiment key**                     | `null`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Roles**                             | owner, 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.

|                  Rank | Resource                     | Total bytes | Used bytes |    Unused |   Coverage % | Recommendation                                     |
| --------------------: | ---------------------------- | ----------: | ---------: | --------: | -----------: | -------------------------------------------------- |
|                     1 | `stencil-bundle.css` (theme) |       134KB |       52KB |      82KB |          39% | PurgeCSS to remove unused theme rules              |
|                     2 | `klaviyo-popup.css`          |        28KB |        4KB |      24KB |          14% | Defer load; popup styles unused on most page-loads |
|                     3 | `tidio-chat.css`             |        22KB |        6KB |      16KB |          27% | Defer chat widget CSS to post-load                 |
|                     4 | `web-fonts.css`              |        12KB |        8KB |       4KB |          67% | Inline critical font-face declarations             |
|                     5 | `cookie-consent.css`         |         8KB |        6KB |       2KB |          75% | Acceptable; small bytes                            |
| **Total CSS shipped** |                              |   **204KB** |   **76KB** | **128KB** | **37% 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 horizon  | Action                                                         |
| ------------- | -------------------------------------------------------------- |
| First 1 hour  | Identify top 3 entries.                                        |
| First 7 days  | Configure PurgeCSS in build pipeline; tree-shake theme bundle. |
| First 14 days | Defer third-party widget CSS (Klaviyo, chat).                  |
| Re-audit      | Confirm CSS bytes dropped as expected.                         |

## Sibling cards merchants should reference together

| Card                                                                                              | Why merchants reach for it                                             |
| ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| [`psi_unused_js`](/nerve-centre/kpi-cards/website-performance/unused-javascript)                  | Same pattern for JavaScript; higher impact, prioritise first.          |
| [`psi_render_blocking`](/nerve-centre/kpi-cards/website-performance/render-blocking-resources)    | Render-blocking CSS overlaps with unused CSS; deferring helps both.    |
| [`psi_total_weight`](/nerve-centre/kpi-cards/website-performance/total-page-weight)               | Total page weight; CSS bytes contribute.                               |
| [`psi_top_opportunities_bytes`](/nerve-centre/kpi-cards/website-performance/top-opportunities)    | Composite byte-savings ranking.                                        |
| [`psi_top_opportunities_ms`](/nerve-centre/kpi-cards/website-performance/top-opportunities)       | Composite millisecond-savings ranking.                                 |
| [`psi_perf_score_summary`](/nerve-centre/kpi-cards/website-performance/performance-score-summary) | Composite score; CSS work indirectly supports LCP improvement.         |
| [`crux_lcp_p75`](/nerve-centre/kpi-cards/website-performance/page-load-speed)                     | LCP improves when render-blocking CSS is deferred.                     |
| [`psi_third_party_cost`](/nerve-centre/kpi-cards/website-performance/third-party-cost)            | Third-party widgets ship CSS that often dominates the unused-CSS list. |

## Reconciling against the vendor's own dashboard

**Where to look:**

* **[PageSpeed Insights](https://pagespeed.web.dev)**, "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:**

| Reason                                                                                                                                                                                           | Direction                     | What 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-report** | Use 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 Lighthouse  | Add manual checks for small-CSS patterns if needed.                   |

**Cross-connector reconciliation:** primarily internal (with [`psi_render_blocking`](/nerve-centre/kpi-cards/website-performance/render-blocking-resources), [`psi_total_weight`](/nerve-centre/kpi-cards/website-performance/total-page-weight), [`psi_third_party_cost`](/nerve-centre/kpi-cards/website-performance/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](https://app.vortexiq.ai/login) or [book a demo](https://www.vortexiq.ai/contact-us) to see this metric running on your own data.
