10 Proven Strategies to Achieve Perfect Google Lighthouse Scores in Next.js

Letícia Caldeirão

2025-11-28

10 Proven Strategies to Achieve Perfect Google Lighthouse Scores in Next.js

A slow website is a dead website. Google reports that 53% of mobile users abandon sites that take over 3 seconds to load. That's why achieving high Google Lighthouse scores isn't just about bragging rights—it's about business survival.

At Backpack Works, we've optimized dozens of Next.js applications to achieve perfect or near-perfect Lighthouse scores. Here are our battle-tested strategies that actually work.

Understanding Lighthouse Metrics

Before diving into optimizations, let's understand what we're optimizing for:

Core Web Vitals:

• LCP (Largest Contentful Paint): Should be under 2.5 seconds
FID (First Input Delay): Should be under 100 milliseconds
CLS (Cumulative Layout Shift): Should be under 0.1

Other Key Metrics:

• FCP (First Contentful Paint): When content first appears
TTI (Time to Interactive): When the page becomes usable
TBT (Total Blocking Time): Time the main thread is blocked

1. Optimize Your Images (The Biggest Win)

Images are usually the largest performance killer. Next.js's Image component is your secret weapon.

Before:

<img src="/hero.jpg" alt="Hero image" />


After:

import Image from 'next/image'

<Image
src="/hero.jpg"
alt="Hero image"
width={1920}
height={1080}
priority // For above-the-fold images
placeholder="blur"
blurDataURL={blurDataUrl}
/>


Pro Tips:

• Use WebP format (30% smaller than JPEG)
• Set explicit width and height to prevent CLS
• Use priority for hero images
• Implement blur placeholders for better perceived performance

2. Implement Code Splitting

Don't load code users don't need. Use dynamic imports to split your bundles.

import dynamic from 'next/dynamic'

// Only load heavy component when needed
const HeavyChart = dynamic(() => import('../components/HeavyChart'), {
loading: () => <div>Loading chart...</div>,
ssr: false
})


This can reduce your initial bundle by 30-50%.

Ready to get started? Let’s talk now!

3. Optimize Your Fonts

Fonts can cause layout shifts and slow loading. Next.js 13+ has built-in font optimization:

import { Inter } from 'next/font/google'

const inter = Inter({
subsets: ['latin'],
display: 'swap', // Prevents invisible text
preload: true,
variable: '--font-inter'
})

4. Use Static Generation Whenever Possible

Static pages are fastest. Use ISR (Incremental Static Regeneration) for dynamic content:

export async function getStaticProps() {
const data = await fetchData()

return {
props: { data },
revalidate: 3600 // Regenerate every hour
}
}

5. Minimize JavaScript Bundle Size

Use the bundle analyzer to find bloat:

npm install @next/bundle-analyzer
Copy code


// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true'
})

module.exports = withBundleAnalyzer({})


Run with: ANALYZE=true npm run build

Common fixes:

• Replace moment.js with date-fns (70% smaller)
• Use lodash-es with tree shaking
• Lazy load heavy components

6. Implement Proper Caching

Configure caching headers for static assets:

// next.config.js
module.exports = {
async headers() {
return [
{
source: '/:all*(svg|jpg|jpeg|png|gif|ico|webp)',
headers: [{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable'
}]
}
]
}
}

7. Optimize Third-Party Scripts

Third-party scripts can destroy performance. Load them strategically:

import Script from 'next/script'

<Script
src="https://www.googletagmanager.com/gtag/js"
strategy="afterInteractive" // Load after page is interactive
/>

Strategy options:

• beforeInteractive: Critical scripts
• afterInteractive: Important but not critical
• lazyOnload: Can wait until idle

8. Reduce Cumulative Layout Shift

Prevent layout shifts by:

Setting image dimensions:

<Image width={400} height={300} ... />


Reserving space for dynamic content:

.skeleton {
min-height: 200px; /* Reserve space */
}


Using CSS aspect-ratio:

.video-container {
aspect-ratio: 16 / 9;
}

9. Optimize for Mobile

Lighthouse primarily scores mobile performance. Key optimizations:

• Use responsive images with sizes attribute
• Reduce JavaScript for mobile devices
• Test with CPU throttling enabled
• Minimize main thread work

10. Monitor Real User Metrics

Lab data isn't everything. Monitor real user experience:

import { getCLS, getFID, getLCP } from 'web-vitals'

function sendToAnalytics(metric) {
// Send to your analytics
console.log(metric)
}

getCLS(sendToAnalytics)
getFID(sendToAnalytics)
getLCP(sendToAnalytics)

Common Pitfalls to Avoid

  1. Overusing Client-Side Rendering
    Default to SSG/SSR. Only use CSR when necessary.

  2. Loading Everything Upfront
    Lazy load below-the-fold content and non-critical features.

  3. Ignoring Mobile Performance
    Always test mobile first. Desktop scores can be misleading.

  4. Not Testing with Throttling
    Test with 4x CPU slowdown and Fast 3G to simulate real conditions.

Real-World Results

Here are actual improvements we've achieved for clients:

• E-commerce site: 45 → 98 Performance score, 35% increase in conversions
SaaS platform: 62 → 95 Performance score, 50% reduction in bounce rate
Marketing site: 71 → 100 Performance score, 2x improvement in Core Web Vitals

Quick Wins Checklist

Start with these for immediate improvements:

○ Replace <img> with Next.js <Image>
○ Add priority to above-the-fold images
○ Implement font optimization with next/font
○ Enable static generation where possible
○ Lazy load heavy components
○ Add proper caching headers
○ Optimize third-party script loading
○ Set explicit dimensions on images and videos
○ Remove unused JavaScript and CSS
○ Test on mobile with throttling

Conclusion

Achieving perfect Lighthouse scores in Next.js isn't magic—it's methodical optimization. Start with images (biggest impact), then tackle JavaScript bundle size, and finally fine-tune with caching and lazy loading.

Remember: Performance is a feature, not a nice-to-have. Every 100ms of improvement can increase conversions by 1%.

At Backpack Works, we don't just build websites—we build fast websites. Need help optimizing your Next.js application? Let's talk about transforming your Lighthouse scores and your business metrics.

Related articles

Thoughts on building, scaling & shipping