Next.js Performance Optimization: Beyond the Basics
Next.js is fast out of the box, but there's always room for improvement. Here are the optimization techniques that actually moved the needle for my projects.
Image Optimization Done Right
Use Next.js Image component, but configure it properly:
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // For above-the-fold images
placeholder="blur" // Smooth loading
blurDataURL="data:image/..." // Tiny base64 preview
/>
The priority prop is crucial for LCP (Largest Contentful Paint). Use it for your hero images.
Font Optimization
Use next/font to eliminate layout shift:
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
This loads fonts optimally and prevents FOUT (Flash of Unstyled Text).
Dynamic Imports for Heavy Components
Don't load everything upfront:
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('@/components/Chart'), {
loading: () => <p>Loading chart...</p>,
ssr: false, // Skip SSR for client-only components
});
This can shave hundreds of KB from your initial bundle.
Streaming with Suspense
For data-heavy pages, stream content as it becomes available:
import { Suspense } from 'react';
export default function Page() {
return (
<div>
<Header />
<Suspense fallback={<Skeleton />}>
<SlowDataComponent />
</Suspense>
<Footer />
</div>
);
}
Users see something immediately, not a blank page.
Bundle Analysis
Run this regularly:
ANALYZE=true npm run build
Add this to next.config.js:
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// your config
});
You'll be surprised what's bloating your bundle.
Caching Strategies
Leverage Next.js caching:
// Revalidate every hour
export const revalidate = 3600;
// Or use on-demand revalidation
export async function GET() {
revalidatePath('/posts');
return Response.json({ revalidated: true });
}
Smart caching can make your app feel instant.
Key Metrics to Track
Focus on these Core Web Vitals:
- LCP: Largest Contentful Paint (under 2.5s)
- FID: First Input Delay (under 100ms)
- CLS: Cumulative Layout Shift (under 0.1)
Use Lighthouse and real user monitoring to track them.
The Real Secret
The best optimization is often not adding the feature in the first place. Before optimizing, ask: do users actually need this?
Performance optimization is a journey, not a destination. Start with the basics, measure everything, and optimize what matters.