Part III β The Speed Β· Lesson 5.5
Network Optimization
In one lineFewer round trips, closer bytes, fewer bytes β in that order, because that's the order of impact.
Where you've seen itThe hero image that only starts downloading once the JavaScript that references it has parsed.
Diagram
BEFORE β discovery chain, 3.6s to LCP
document ββββ
app.js ββββββββββ
api/config ββββ
hero.jpg ββββββββ β discovered last
ββββββ¬βββββ¬βββββ¬βββββ¬βββββ¬βββββ¬βββββ€
0 0.5 1.0 1.5 2.0 2.5 3.0 3.6s
AFTER β preload + preconnect + parallel, 1.9s to LCP
document ββββ
hero.jpg ββββββββ β preload in <head>, starts immediately
app.js ββββββββββ β in parallel
api/config ββββ β preconnect saved the handshake
ββββββ¬βββββ¬βββββ¬βββββ¬βββββ€
0 0.5 1.0 1.5 1.9s
Nothing got smaller. The order changed.RESOURCE HINTS β tell the browser what it can't discover yet
<link rel="preconnect" href="https://api.example.com">
ββ DNS + TCP + TLS done early saves ~100β300ms
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high">
ββ start now, I need this for LCP
<link rel="preload" as="font" type="font/woff2" crossorigin href="...">
ββ fonts are discovered late (inside CSS) β always preload
<link rel="prefetch" href="/next-page.js">
ββ idle-time fetch for the NEXT navigation
Budget: 2β3 preloads. Preloading everything = preloading nothing.BYTES β the cheap wins, ranked
1. images AVIF/WebP Β· responsive srcset Β· lazy-load below fold
(images are typically 50%+ of page weight)
2. compress Brotli > gzip for text Β· ~15% smaller
3. fonts woff2 Β· subset Β· font-display: swap Β· max 2 weights
4. JS see 5.7 β usually the hardest and most valuableHow it works
- Cut round trips first.
preconnectto third-party origins,preloadthe LCP resource and fonts, and break dependency chains so requests start in parallel. - Move bytes closer. A CDN turns a 200ms origin fetch into a 30ms edge hit for everything cacheable.
- Then cut bytes. Modern image formats, Brotli, subset fonts, and route-level code splitting.
- Set
fetchpriorityto tell the browser which image matters βhighon the hero,lowon carousels below the fold. - Lazy-load below the fold with
loading="lazy"on images and iframes, but never on the LCP element.
<link rel="preconnect" href="https://cdn.example.com">
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high">
<img src="/hero.avif" width="1200" height="600" alt="β¦"
fetchpriority="high"> <!-- LCP: never lazy -->
<img src="/below.avif" width="400" height="300" alt="β¦"
loading="lazy" decoding="async">Trade-offs
| Technique | Win | Watch out |
|---|---|---|
preconnect | 1β2 RTT per origin | Limit to 3β4; each costs a socket |
preload | Starts LCP resource immediately | Over-use starves other requests |
| CDN | 100β300ms per request | Cache invalidation strategy |
| Brotli | ~15% over gzip | Slower to compress β do it at build time |
loading="lazy" | Fewer bytes on first load | Applied to the LCP image, it hurts |
Interview angle
"The hero image is the LCP element and it's slow. Fix it."
- First ask when it starts, not how long it takes β usually it's discovered late inside CSS or JS.
preloadwithfetchpriority="high", serve AVIF/WebP withsrcset, and set explicit dimensions to protect CLS.- Then check the origin: a slow TTFB delays everything downstream regardless of image size.
Recap
- Round trips beat bytes; discovery order beats file size.
- Preload the LCP image and fonts, preconnect to third-party origins, cap both.
- Never lazy-load the LCP element β the single most common self-inflicted regression.