Boosting Lighthouse Scores in Next.js
When optimizing a landing page I built with Next.js, my goal was simple. push the performance score as high as possible. Next.js already handles a lot under the hood such as code splitting, image optimization, and lazy loading, but true performance gains often come from attention to detail.
Here are a few lessons that made the biggest difference:
1. Think About Performance from Day One
Performance isn’t an afterthought. Fixing it at the end can be painful. Building with optimization in mind from the start saves hours of debugging later.
You can regularly check your site’s speed using Lighthouse (in Chrome DevTools) or Google PageSpeed Insights. They measure key metrics like:
- TTL (Time to Load): How long it takes for your page to fully load.
- LCP (Largest Contentful Paint): How quickly the main content (like a hero image or headline) appears.
- FID (First Input Delay): How fast the page responds when a user interacts for the first time.
- CLS (Cumulative Layout Shift): How stable the layout is while loading.
Keeping these metrics in check ensures your page not only loads fast but also feels fast.
2. Use Modern Image Formats
Prefer .webp over .png or .jpg. WebP images are typically 25–35% smaller while maintaining the same visual quality, helping browsers render content faster and use less bandwidth.
You can convert your images to WebP using Squoosh, a free tool that allows you to compress, preview, and export optimized images easily.
3. Match Image Resolution to Usage
I initially made the mistake of using a 400×400 image inside a 50×50 container, which slowed things down unnecessarily. Scaling large images in the browser increases load time and wastes resources.
Make sure your images match their actual display size. Tools like Squoosh can also resize your images before exporting so you serve only what’s needed.
4. Use Separate Images for Mobile and Desktop
Large desktop images can hurt performance on mobile. A 2000px-wide hero image might look great on desktop but will slow down smaller screens.
To fix this, use responsive images with the Next.js <Image> component and define multiple image sizes using the sizes or srcSet attributes. This ensures each device only downloads the image it needs.
You can also use Squoosh to create two versions of each image, one optimized for desktop and another for mobile, both in .webp format.
5. Test Production Builds, Not Dev
Lighthouse scores can vary widely between development and production. My score jumped from under 80% in development to above 95% once I tested the production build.
There are two main ways to run a production build locally:
Option A: Run the Next.js production server (for SSR/ISR sites)
npm run build
npm run start
Option B: Export a static site and serve it locally
App Router (Next 13+):
// in next.config.js
module.exports = {
output: 'export',
};
Then:
npm run build
npx next export # creates the out/ folder
npx serve@latest out
Note: Static exports do not support SSR, API routes, or on-demand rendering. Use this only for fully static pages.
Conclusion
When building fast and efficient web pages with Next.js, keep the following in mind:
- Measure performance early and often using Lighthouse or PageSpeed Insights.
- Optimize images with modern formats like
.webp. - Always match image resolution to its display size.
- Use separate images for mobile and desktop to avoid unnecessary downloads.
- Test production builds rather than relying on development mode.
- Keep an eye on key metrics such as LCP, FID, and CLS for a smoother user experience.
- Build with efficiency in mind from the start rather than treating performance as an afterthought.