CSS Performance

GPU-Friendly Properties, content-visibility, Critical CSS

CSS Performance

Most CSS is fast. A few properties cause expensive layout or paint — and a few modern features unlock big wins.

4 min read Level 2/5 #css#performance#layout
What you'll learn
  • Pick GPU-friendly properties for animation
  • Use `content-visibility` for long pages
  • Inline critical CSS

CSS is usually not the bottleneck — but a few habits keep it fast.

Animate transform and opacity Only

Browsers can offload transform and opacity to the GPU. Animate anything else (top, left, width, margin) and the browser must re-layout the page every frame.

/* ✗ Slow — causes layout every frame */
.menu { transition: left 200ms ease; }
.menu.open { left: 0; }

/* ✓ Fast — GPU-handled */
.menu { transition: transform 200ms ease; transform: translateX(-100%); }
.menu.open { transform: translateX(0); }

will-change — Use Sparingly

.about-to-animate { will-change: transform; }

Tells the browser “this element will animate” so it can prepare. Overusing it actually HURTS performance — only set it shortly before the animation and remove it after.

content-visibility: auto — Skip Off-Screen Rendering

.long-section {
  content-visibility: auto;
  contain-intrinsic-size: 0 500px;   /* estimated size for scrolling */
}

The browser skips laying out and painting children of this element when they’re off-screen. Big win for long pages with many similar sections.

Avoid Expensive Selectors (Rarely)

Universal selectors (*), wildcards ([class^="..."]), and very deep descendant chains (body div .foo span a) are slower than plain class selectors. Modern browsers handle this well — worry about it only on huge pages with thousands of elements.

Critical CSS

The browser blocks rendering until external CSS arrives. For above-the-fold content, inline the critical styles in a <style> block in <head>:

<head>
  <style>
    /* critical CSS for the header and hero */
    body { font-family: system-ui; margin: 0; }
    .header { padding: 1rem; ... }
  </style>
  <link rel="stylesheet" href="/main.css" media="print" onload="this.media='all'" />
</head>

The print / onload trick loads the rest of the CSS without blocking render.

Loading Strategy

  • Preload key fonts and CSS<link rel="preload" ...>
  • Avoid @import in production — it serializes downloads
  • Minify and gzip — most build tools do this automatically
  • Use modern formatsfont-display: swap for fonts, AVIF / WebP for images

Up Next

DevTools tips for debugging performance and layout.

DevTools Debugging →