Making a Next.js site actually fast
Where the time went on a 3,000-listing marketplace, and what moved the numbers.
The marketplace scored 41 on mobile when I joined and 92 when I left. Almost none of that came from the framework. It came from images, third-party scripts and a handful of components that rendered far more than they showed.
Images first
Every listing had a hero image sized for desktop and served to phones. Switching to next/image with real sizes attributes cut the transferred bytes on the listing page by two thirds before I touched any code.
Then the scripts
Two analytics tags, a chat widget and a map SDK loaded on every route. Deferring them until after interaction, and dropping the map from the listing page entirely, took a full second off time-to-interactive.
Measure on the phone your users have, not the one in your pocket.
Then the rendering
The listing grid rendered every card’s full detail and hid most of it with CSS. Rendering only what was visible - and virtualising the grid past forty items - fixed the scroll jank that no amount of image work had touched.
What did not matter
Switching state libraries. Memoising everything. A faster build. All tempting, all measured, none of them moved the numbers users could feel.