| name | performance |
| description | Next.js performance optimization — Core Web Vitals, ISR/SSG strategy, bundle analysis, image optimization, and runtime performance patterns. Use when diagnosing slow pages, optimizing Core Web Vitals, or reviewing production performance. |
Next.js Performance
Systematic approach to optimizing Next.js applications.
Performance Dimensions
1. Rendering Strategy
Pick the right strategy per route:
| Strategy | Use Case | Trade-off |
|---|
| Static (SSG) | Public content, blog, docs | Fastest, no server load, stale on update |
| ISR | Content that changes periodically | Revalidate on demand or by time |
| Dynamic (SSR) | User-specific, auth-gated | Always fresh, server cost per request |
| Streaming | Routes with slow data dependencies | Faster TTFB, progressive rendering |
Rule of thumb: Static by default, dynamic by necessity.
2. Bundle Optimization
ANALYZE=true npm run build
npx cost-of-modules
Key areas:
- Dynamic imports for heavy components (
next/dynamic)
- Tree-shake unused imports
- Avoid barrel exports (
index.ts re-exports hurt tree-shaking)
- Use
react-compiler where possible
import dynamic from 'next/dynamic'
const HeavyChart = dynamic(() => import('./heavy-chart'), {
loading: () => <ChartSkeleton />
})
3. Image Optimization
Use next/image everywhere:
import Image from 'next/image'
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
sizes="100vw"
/>
Rules:
- Always provide
width and height (prevents layout shift)
- Use
priority for LCP images (hero, main banner)
- Use
sizes for responsive images
- Host images on a CDN (or use remote patterns)
4. Font Optimization
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
- Always use
next/font (self-hosts, eliminates external requests)
- Use
display: 'swap' for better perceived performance
5. Core Web Vitals Checklist
| Metric | Target | Common Fixes |
|---|
| LCP | ≤ 2.5s | Optimize hero image (priority), reduce TTFB, preload key resources |
| FID / INP | ≤ 200ms | Break up long tasks, lazy load below-fold, avoid heavy JS on main thread |
| CLS | ≤ 0.1 | Set dimensions on images/videos, avoid layout shifts from dynamic content |
6. Route Segment Optimization
app/
blog/
page.tsx
[slug]/
page.tsx
loading.tsx
- Each segment can have its own
loading.tsx (streaming boundary)
- Long page + slow section → extract into
page.tsx with <Suspense>
Measurement
npx @next/codemod@latest optimize
Checklist