Browser Performance That Matters
Real measurements using Chrome DevTools Protocol. Not theoretical — actual browser rendering performance.
Key Findings
Every CSS class on every element is work for the browser — parsing, matching, calculating styles. With utility-first CSS, a typical element has 10-20+ classes. Multiply by hundreds of elements = massive overhead.
Classpresso consolidates repeated class patterns at build time, dramatically reducing browser work.
1The Hidden Cost of Utility Classes
Utility-first CSS frameworks like Tailwind, Bootstrap, and Bulma are incredibly productive. But there's a performance cost browsers pay on every page load:
For EACH element on the page, the browser must: ──────────────────────────────────────────────────────────────── 1. Parse class attribute → Split "flex items-center justify-center rounded-md text-sm font-medium..." into individual tokens 2. Match each class → Look up each class in stylesheets, check specificity, handle conflicts 3. Calculate final styles → Combine all matching rules, resolve inheritance, compute used values 4. Store in CSSOM → Allocate memory for computed style object ──────────────────────────────────────────────────────────────── With 15 classes × 500 elements = 7,500 class lookups per page With 15 classes × 1000 elements = 15,000 class lookups per page
The problem: Repeated class patterns (like button styles that appear 50 times) cause the browser to do the same work 50 times. That's wasted CPU cycles on every single page load.
2Benchmark: 500 Complex Components
Test page with 500 components, each containing multiple nested elements with typical Tailwind-style utility classes (buttons, cards, inputs, badges, nav items).
| Metric | Unoptimized | With Classpresso | Improvement |
|---|---|---|---|
| Style Recalculation | 12.4ms | 7.8ms | 37% faster |
| Layout Duration | 8.2ms | 5.9ms | 28% faster |
| First Paint | 245ms | 169ms | 31% faster |
| Memory Usage | 18.7 MB | 15.2 MB | 19% less |
3Benchmark: 1000 Complex Components
Stress test with 1000 components. This simulates complex dashboards, data tables, and content-heavy applications.
| Metric | Unoptimized | With Classpresso | Improvement |
|---|---|---|---|
| Style Recalculation | 28.6ms | 14.3ms | 50% faster |
| Layout Duration | 18.4ms | 11.1ms | 40% faster |
| First Paint | 412ms | 239ms | 42% faster |
| Memory Usage | 34.2 MB | 27 MB | 21% less |
Key insight: Performance gains scale with page complexity. The more repeated patterns you have, the bigger the improvement. Data tables, dashboards, and component-heavy pages benefit most.
4Why Browser Performance Matters More Than Bundle Size
Bundle Size Savings
HTML might be 50-60% smaller. On modern networks, this saves ~100ms on 3G.
Rendering Performance
50% faster style calculation happens on every page load,every DOM change, every interaction.
When does style recalculation happen? ──────────────────────────────────────────────────────────────── 1. Initial page load → EVERY element needs styles computed 2. DOM mutations → React/Vue re-renders trigger recalc 3. Class changes → Adding/removing classes triggers recalc 4. Pseudo-class changes → :hover, :focus trigger recalc 5. Window resize → Media queries trigger recalc 6. Scroll → position: sticky, lazy loading trigger recalc ──────────────────────────────────────────────────────────────── A typical SPA might trigger 100+ style recalculations per minute during normal user interaction. 50% faster × 100 = HUGE savings.
5Works With All Utility-First Frameworks
Classpresso optimizes any utility-first CSS framework. The more classes per element, the more it helps.
Zero code changes required. Classpresso runs on your build output. Your React, Vue, Svelte, or vanilla HTML stays exactly the same.
6Benchmark Methodology
Test Environment ──────────────────────────────────────────────────────────────── Browser: Chromium (via Playwright) CPU: Throttled 4x (simulates mobile device) Network: Local server (network not a factor) Runs: 5 iterations averaged per test Metrics Collected (Chrome DevTools Protocol) ──────────────────────────────────────────────────────────────── - Performance.getMetrics() → RecalcStyleDuration, LayoutDuration - performance.timing → First Paint, First Contentful Paint - performance.measureUserAgentSpecificMemory() → JS Heap Test Page Structure ──────────────────────────────────────────────────────────────── Each "component" contains: - 1 card container (8 classes) - 1 header (12 classes) - 1 button (15 classes) - 1 badge (6 classes) - 1 input (12 classes) Total: ~53 classes per component 500 components = ~26,500 class instances 1000 components = ~53,000 class instances
All benchmark code is available in the repository. Run npm run benchmark to reproduce results on your machine.
+Bonus: Network Savings
HTML size reduction is a nice bonus, though not the primary benefit:
| Page Type | Original HTML | Optimized | Saved |
|---|---|---|---|
| Simple page (20 components) | 45 KB | 32 KB | 29% |
| Dashboard (100 components) | 180 KB | 85 KB | 53% |
| Data table (500 rows) | 420 KB | 165 KB | 61% |
On slow 3G (400 Kbps), a 60% reduction saves ~500ms. But the real win is the 50% faster rendering that happens every single time the page loads.
Faster rendering. Less memory. Zero runtime cost.
Works with Tailwind, Bootstrap, Bulma, Tachyons, UnoCSS, and any utility-first CSS framework.
Make your utility CSS render faster
Get started with Classpresso in under 5 minutes.