The brief
A product page on a Slow 4G connection: 150 ms round trip, 1.2 Mbit. Everything that could be wrong with it is wrong with it, and every fault is one you have already met in this course.
The constraint is the one that makes performance work hard: nothing may be removed. The font, the hero, the charts and the analytics all still have to exist when you are done. The only thing that changes is when and how they load.
The eight faults
Work in that order and each fix makes the next one easier to see. Fix the shifts first and you will still be looking at an 11-second LCP.
| Signal | Lesson |
|---|---|
| A 90 KB HTML document | server — think time and bytes before anything can start |
| A 120 KB render-blocking stylesheet | the critical path |
| A font four hops deep, on a second origin | network, fonts |
The hero image waiting on app.js | LCP — discovery, not bandwidth |
| 495 KB of JavaScript at boot | JavaScript cost |
| Three origins | network — one connection setup each |
| HTTP/2 | network — a round trip you can have back |
| Two unreserved shifts | CLS |
What "fixed" means here
- LCP under 2500 ms, and
rate()saysgood. - CLS exactly zero — reserved space, not smaller jumps.
- Total blocking time at or under 150 ms.
- Nothing deleted. Every module still exists, and every kind of resource is still on the page.
The moves available to you
A smaller document. Critical CSS instead of the whole stylesheet. Self-hosting, which removes both the extra origins and the chain. A subset font, preloaded. An AVIF hero, discovered from the document. Deferring the modules the first screen never touches. HTTP/3. Reserved boxes for anything that arrives late.
Each one is worth measuring on its own — the point of the lab is not to arrive at the answer, it is to be able to say which change bought which millisecond.