How to Score 100/100 on Google Lighthouse with Next.js
Is your website slow? Learn how to fix Core Web Vitals and hit a perfect Lighthouse score using Next.js features like next/image, font optimization, and lazy loading.
We have all been there: you build a beautiful website, deploy it, and then run a Google Lighthouse audit... only to see a performance score of 45/100.
In 2025, performance isn't just about user experience—it is a direct ranking factor for SEO. If your site is slow, Google will rank it lower.
Since I work primarily with Next.js, I have found that achieving a perfect 100 score is actually straightforward if you use the framework's built-in tools correctly. Here are 4 technical techniques to speed up your site immediately.
1. Stop Using the <img> Tag
The biggest killer of page speed is unoptimized images. If you use a standard HTML <img> tag, the browser downloads the full-resolution image even if the user is on a tiny mobile screen.
Instead, use the Next.js Image component. It automatically resizes images, converts them to modern formats like WebP or AVIF, and prevents layout shift (CLS).
import Image from 'next/image'
import heroPic from '../public/hero.jpg'
export default function Hero() {
return (
<Image
src={heroPic}
alt="Hero Image"
placeholder="blur" // Shows a blur effect while loading
priority // Use this ONLY for the main image above the fold
/>
)
}
2. Eliminate Layout Shift with next/font
Have you ever started reading a page, and suddenly the text jumps because a custom font finally loaded? That is called "Flash of Unstyled Text" (FOUT), and it hurts your "Cumulative Layout Shift" score.
Next.js has a built-in font system that hosts Google Fonts locally at build time. No more external requests to Google servers.
// layout.js
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
3. Lazy Load Heavy Components
If you have a heavy component—like a 3D model, a massive chart, or a complex map—do not load it until the user actually sees it.
Use next/dynamic to lazy load these components. This reduces the initial JavaScript bundle size (TBT) significantly.
import dynamic from 'next/dynamic'
// This component won't load until the user scrolls to it
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <p>Loading chart...</p>,
ssr: false // Disable server-side rendering for browser-only libs
})
4. Tame Third-Party Scripts
Analytics, chatbots, and ads are notorious for slowing down the "Time to Interactive." If you load them in the <head>, they block the rest of your page from loading.
Use the Script component with the strategy prop to delay them.
import Script from 'next/script'
// 'lazyOnload' waits until the browser is idle to load this script
<Script
src="https://example.com/chat-widget.js"
strategy="lazyOnload"
/>
Conclusion
Getting a 100/100 score isn't magic; it's just efficient coding. By switching to next/image, self-hosting fonts, and lazy-loading heavy assets, you can drastically lower your load times.
Run a Lighthouse audit on your site today. If you are in the red, try applying just one of these fixes—you will see the difference instantly.
Enjoyed this article?
Share it with your network or friends.