Phase 5Tooling & Production

#19 Performance

critical CSS, lazy loading, minification

Why CSS performance matters

CSS can significantly impact page load speed and user experience. Unoptimized CSS leads to render-blocking, layout shifts, and slow paint times.

Critical CSS

Critical CSS is the minimal CSS needed to render above-the-fold content. Inline it for faster first paint:

Critical CSS strategy
<!-- Inline critical CSS in <head> -->
<style>
  body { font-family: system-ui, sans-serif; margin: 0; }
  .hero { min-height: 100vh; display: grid; place-items: center; }
  .nav { position: fixed; top: 0; width: 100%; }
</style>

<!-- Load rest of CSS asynchronously -->
<link rel="preload" href="style.css" as="style"
  onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>

CSS minification

Minify with cssnano
npm install cssnano

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer'),
    require('cssnano')({
      preset: 'default',
    }),
  ],
}

Lazy loading images

Native lazy loading
<!-- Native lazy loading -->
<img src="photo.jpg" alt="Photo" loading="lazy" width="800" height="600">

<!-- Eager load above-the-fold images -->
<img src="hero.jpg" alt="Hero" loading="eager" fetchpriority="high">

Avoiding layout shifts

Prevent CLS
/* Always set width and height on images */
img {
  max-width: 100%;
  height: auto;
}

/* Use aspect-ratio for responsive containers */
.video-wrapper {
  aspect-ratio: 16 / 9;
  width: 100%;
}

/* Reserve space for dynamic content */
.ad-slot {
  min-height: 250px;
}

Efficient selectors

Selector performance
/* ✓ Good: simple selectors */
.card-title { }
.nav-link { }

/* ✗ Avoid: deeply nested selectors */
.page .content .sidebar .widget .title { }

/* ✗ Avoid: universal selector in descendants */
.card * { }

/* ✓ Good: reduce unused CSS */
/* Use tools like PurgeCSS to remove unused styles */

Your turn

Try the performance commands below:

terminal — npm
user@stemlegacy:~/my-project$