Tailwind CSS Performance Optimization v4 Performance Improvements
Tailwind CSS v4 features a completely rewritten engine in Rust:
Metric v3 v4 Full builds Baseline Up to 5x faster Incremental builds Milliseconds Microseconds (100x+) Engine JavaScript Rust JIT (Just-In-Time) Compilation How JIT Works
JIT generates styles on-demand as classes are discovered in your files:
Scans source files for class names Generates only the CSS you use Produces minimal, optimized output v4: Always JIT
Unlike v3, JIT is always enabled in v4—no configuration needed:
@import "tailwindcss"; / JIT is automatic /
Content Detection Automatic Detection (v4)
v4 automatically detects template files—no content configuration required:
/ v4 - Works automatically / @import "tailwindcss";
Explicit Content (v4)
If automatic detection fails, specify sources explicitly:
@import "tailwindcss"; @source "./src//*.{html,js,jsx,ts,tsx,vue,svelte}"; @source "./components//*.{js,jsx,ts,tsx}";
Excluding Paths @source not "./src/legacy/**";
Tree Shaking How It Works
Tailwind's build process removes unused CSS:
Source: All possible utilities (~15MB+) ↓ Scan: Find used class names ↓ Output: Only used styles (~10-50KB typical)
Production Build
Vite - automatically optimized for production
npm run build
PostCSS - ensure NODE_ENV is set
NODE_ENV=production npx postcss input.css -o output.css
Dynamic Class Names The Problem
Tailwind can't detect dynamically constructed class names:
// BAD - Classes won't be generated
const color = 'blue'
className={text-${color}-500} // ❌ Not detected
const size = 'lg'
className={text-${size}} // ❌ Not detected
Solutions 1. Use Complete Class Names // GOOD - Full class names const colorClasses = { blue: 'text-blue-500', red: 'text-red-500', green: 'text-green-500', } className={colorClasses[color]} // ✓ Detected
- Use Data Attributes // GOOD - Style based on data attributes