How do you optimize images and fonts for fast pages?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
Images: serve modern formats (AVIF/WebP), responsive sizes (srcset/sizes), lazy-load below the fold, and always declare dimensions to avoid layout shift. Fonts: subset to needed glyphs, preload the critical weights, use font-display: swap with metric-matched fallbacks. Media is usually the biggest byte contributor, so it pays first.
Detailed explanation
Images routinely dominate page weight. Format first: AVIF cuts ~50% vs JPEG, WebP ~30% — serve AVIF with WebP/JPEG fallbacks via <picture>. Size second: a 4000px upload rendered at 400px wastes 100x pixels — generate responsive variants and let srcset/sizes pick per viewport and DPR. Loading third: eager + fetchpriority="high" for the LCP hero (plus preload), loading="lazy" with decoding="async" for everything below the fold. Stability fourth: width/height attributes (or aspect-ratio CSS) reserve space so late images never shift layout (CLS). Compression is lossy-by-choice: quality 70–80 is visually identical for photos. Fonts block text two ways: the files are heavy, and invisible/swapping text hurts experience. Subset to latin (+ needed ranges) to shrink files 70%+, preload only the hero weight/style, display=swap to show fallback text immediately, and match fallback metrics (size-adjust, ascent-override) so the swap doesn't shift layout. Self-host instead of third-party font CDNs where possible — one fewer connection chain and full cache control. Verify in DevTools' Network panel (format, transferred size) and the CLS/LCP readouts, not by eyeballing.
Example
<!-- Responsive, lazy, shift-free image -->
<picture>
<source srcset="/hero-800.avif 800w, /hero-1600.avif 1600w" type="image/avif" />
<source srcset="/hero-800.webp 800w, /hero-1600.webp 1600w" type="image/webp" />
<img src="/hero-800.jpg" width="1600" height="900"
loading="lazy" decoding="async" alt="" />
</picture>
/* Swap fast, shift nothing */
@font-face {
font-family: 'Inter';
src: url('/inter-latin.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'Inter-fallback';
src: local('Arial');
size-adjust: 107%; ascent-override: 90%;
}Interview tip
Lead with the ordering — format, size, loading, stability — because it shows method. The size-adjust fallback trick for fonts is the detail that marks real experience.
Common mistakes
- Shipping one giant JPEG for all viewports.
- Lazy-loading the LCP hero image, delaying the main metric.
- Blocking text on custom fonts with no swap or fallback.