Fix the largest element first
Largest Contentful Paint is usually one element: a hero image or a headline blocked by a web font. Identify it, then make that single element load as early as the network allows.
In Next.js that means the priority prop on the hero image, a preconnect to any font origin, and making sure the hero is server rendered rather than assembled after hydration.
- Mark the hero image with priority and explicit dimensions
- Serve AVIF and WebP with a correct sizes attribute
- Self-host fonts through next/font with a matched fallback
- Keep the hero out of any client component that waits on data
Reserve space for everything that arrives late
Cumulative Layout Shift is a discipline problem, not a technical one. Every image needs width and height, every embed needs a reserved container, and every banner that might appear needs its space allocated before it does.
Ship less JavaScript
Interaction to Next Paint punishes long tasks on the main thread. The fastest way to improve it is to send less code in the first place.
Audit which components genuinely need interactivity. In most marketing sites the answer is the navigation, the forms and one or two widgets. Everything else can be a server component.
- Set a JavaScript budget and enforce it in CI
- Dynamically import anything below the fold
- Prefer CSS transitions over animation libraries for simple reveals
- Check the bundle analyser before every release, not after complaints
Verify with field data, not lab data
A perfect Lighthouse run on a fast laptop proves very little. Check the Chrome User Experience Report for real-world numbers, and pay attention to the 75th percentile rather than the median. That is the number Google uses.
