CSS Performance & Optimization
22 min read
Performancecontent-visibilitycontainCritical CSSwill-changeReflowRepaintCore Web VitalsOptimization
The 30 CSS Optimizations You Must Know
CSS performance directly impacts Core Web Vitals. Here are the optimizations every developer should implement.
Rendering Pipeline Impact
| CSS Change | Triggers | Cost |
|---|---|---|
width, height, margin | Layout → Paint → Composite | 🔴 Most Expensive |
color, background, box-shadow | Paint → Composite | 🟡 Moderate |
transform, opacity | Composite only | 🟢 Cheapest |
Key Optimization Checklist
| # | Optimization | Impact |
|---|---|---|
| 1 | Use box-sizing: border-box globally | Prevents layout bugs |
| 2 | Use rem for font sizes (accessibility) | WCAG compliance |
| 3 | Only animate transform and opacity | 60fps animations |
| 4 | Use content-visibility: auto for off-screen content | Faster initial render |
| 5 | Never use !important (except print CSS) | Maintainability |
| 6 | Avoid deep selector nesting (3+ levels) | Faster selector matching |
| 7 | Always set aspect-ratio on images | Prevents CLS |
| 8 | Use font-display: swap | Visible text while fonts load |
| 9 | Inline critical CSS (above-the-fold) | Faster first paint |
| 10 | Purge unused CSS in production | Smaller bundles |
| 11 | Use contain property for isolation | Limits browser recalculations |
| 12 | Use gap instead of margins for flex/grid | Cleaner, more predictable spacing |
| 13 | Use CSS variables for theming | Single source of truth |
| 14 | Prefer <link> over @import | Parallel loading |
| 15 | Minify CSS in production | Smaller file size |
| 16 | Use will-change sparingly | Hints browser for upcoming animations |
| 17 | Use SVGs for icons (not icon fonts) | Sharper, accessible, smaller |
| 18 | Use preconnect for font origins | Faster font loading |
| 19 | Never remove outline without :focus-visible | Accessibility |
| 20 | Use variable fonts (1 file for all weights) | Fewer HTTP requests |
content-visibility: auto
Tells the browser to skip rendering off-screen elements until they're needed. Can improve initial render by 50%+ on long pages.
.section {
content-visibility: auto;
contain-intrinsic-size: auto 500px; /* Estimated height for scroll */
}The contain Property
Isolates a subtree so layout/paint changes don't affect the rest of the page:
| Value | What It Contains |
|---|---|
layout | Layout calculations don't escape this element |
paint | Nothing paints outside this element's bounds |
size | Element's size doesn't depend on children |
style | Counters and quotes don't escape |
strict | All of the above |
content | layout + paint + style |