CSS Budget and Critical CSS Strategy
Plan your CSS performance budget with critical CSS extraction, unused CSS removal, and component-scoped styles. Learn how to keep CSS under 60 KB while maintaining a rich design system.
Detailed Explanation
CSS Budget and Critical CSS
CSS is render-blocking by default — the browser cannot paint anything until it has downloaded and parsed all CSS in the <head>. This makes CSS size directly impact First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
CSS Budget Guidelines
| Site Complexity | CSS Budget | Approach |
|---|---|---|
| Simple (blog) | 15-30 KB | Single stylesheet, utility classes |
| Medium (e-comm) | 30-60 KB | Critical CSS + deferred main sheet |
| Complex (SPA) | 60-100 KB | CSS-in-JS or CSS Modules, code-split |
These are compressed sizes. Uncompressed CSS can be 3-5x larger.
Critical CSS
Critical CSS is the minimum CSS needed to render above-the-fold content. It should be:
- Inlined in the
<head>— No extra HTTP request - Small — Typically 10-15 KB uncompressed (3-5 KB gzip)
- Automatically extracted — Tools like
critical,critters, or Next.js automatic critical CSS
<head>
<style>
/* Critical CSS inlined here - just above-the-fold styles */
.header { ... }
.hero { ... }
.nav { ... }
</style>
<link rel="stylesheet" href="/styles/main.css" media="print" onload="this.media='all'">
</head>
The main stylesheet loads asynchronously using the media="print" trick, so it does not block rendering.
Removing Unused CSS
Large CSS frameworks like Bootstrap (160 KB uncompressed) or Tailwind CSS (3.5 MB uncompressed) ship far more CSS than any single page needs.
- Tailwind CSS — PurgeCSS (built-in) removes unused utilities, reducing output to 5-15 KB
- Bootstrap — Use sass imports to include only the modules you need
- CSS Modules — Scoped per component, tree-shaken by the bundler
CSS-in-JS Considerations
CSS-in-JS libraries (styled-components, Emotion, vanilla-extract) add runtime JavaScript for style injection:
| Library | Runtime Size | Approach |
|---|---|---|
| styled-components | ~15 KB | Runtime injection |
| Emotion | ~11 KB | Runtime injection |
| vanilla-extract | 0 KB | Build-time extraction |
| Tailwind CSS | 0 KB | Utility classes, purged at build |
For performance-critical sites, build-time CSS extraction (vanilla-extract, Tailwind) is preferred over runtime CSS-in-JS.
Monitoring CSS Size
Track CSS file sizes in your bundle analyzer. Watch for:
- CSS files that grow steadily over time (unused styles accumulating)
- Duplicate rules from different components
- Vendor prefixes for browsers you no longer support
Use Case
CSS budget management is essential for sites where First Contentful Paint matters for user engagement and SEO. A marketing site might inline 5 KB of critical CSS and defer a 40 KB main stylesheet, achieving sub-1-second FCP. A component library team might set per-component CSS budgets (e.g., max 2 KB per component) to prevent design system bloat. E-commerce sites benefit from aggressive critical CSS extraction since product pages must render the hero image and price as fast as possible.