Performance optimization is full of cargo-cult advice. Developers spend hours shaving kilobytes off bundles while ignoring the image that takes 3 seconds to load. Here’s what actually moves the needle.
Start With Measurement
You can’t optimize what you don’t measure. Before touching any code:
- Run Lighthouse on your key pages
- Check Core Web Vitals in Google Search Console (real user data)
- Identify the slowest page and the most visited page — start there
The High-Impact Wins
Images (Usually the #1 Problem)
Images account for the majority of bytes on most web pages. Fix this first:
- Use modern formats: AVIF first, WebP as fallback, JPEG as last resort
- Implement responsive images with
srcset— don’t serve desktop images to mobile - Lazy load images below the fold
- Set explicit
widthandheightto prevent layout shift (CLS)
Reduce JavaScript
Every kilobyte of JavaScript costs more than a kilobyte of images because it must be parsed, compiled, and executed:
- Audit your bundle with
webpack-bundle-analyzeror equivalent - Remove unused dependencies ruthlessly
- Code-split routes — users shouldn’t download the settings page when viewing the homepage
- Consider server-side rendering or static generation for content-heavy pages
Font Loading
Custom fonts cause invisible text (FOIT) or layout shifts (FOUT):
- Use
font-display: swapto show fallback text immediately - Preload your primary font file
- Subset fonts to include only the characters you use
- Consider system font stacks for body text
The Diminishing Returns Zone
After the big wins, further optimization has diminishing returns. Don’t spend a week optimizing a 200ms server response when your 2MB hero image loads in 4 seconds.
Focus on what users actually experience, not what benchmarks measure.