Next.js Performance
Expert guidance for optimizing Next.js applications.
Quick Reference
| Concern |
Solution |
Impact |
| Images |
next/image with sizing |
CLS prevention, auto-optimization |
| Fonts |
next/font |
No layout shift, self-hosted |
| Heavy components |
next/dynamic |
Reduced initial bundle |
| Data caching |
fetch options (revalidate) |
Reduced server load |
| Client navigation |
Link component |
Instant transitions |
| Bundle size |
Tree shaking, no unused deps |
Faster JS loading |
What Do You Need?
- Image optimization - next/image usage, sizing, formats
- Font loading - next/font, preloading
- Code splitting - Dynamic imports, route splitting
- Caching - ISR, revalidation, cache strategies
- Navigation - Link usage, prefetching
Specify a number or describe your performance concern.
Routing
| Response |
Reference to Read |
| 1, "image", "img", "optimization", "cls" |
images.md |
| 2, "font", "layout shift", "typography" |
fonts.md |
| 3, "dynamic", "import", "lazy", "split" |
code-splitting.md |
| 4, "cache", "revalidate", "isr", "fetch" |
caching.md |
| 5, "navigation", "link", "prefetch" |
navigation.md |
Essential Principles
Optimize images: Use next/image with width/height for all images. Prevents CLS and enables automatic optimization.
Self-host fonts: Use next/font to eliminate requests to external font services and prevent layout shift.
Dynamic import heavy code: Use next/dynamic for components that are heavy or not immediately visible.
Client-side navigation: Use Link component for all internal links. Enables instant page transitions.
Cache strategically: Use appropriate fetch caching (force-cache, no-store, revalidate) based on data freshness needs.
Common Performance Issues
| Issue |
Severity |
Impact |
Fix |
Using <img> instead of next/image |
High |
CLS, no optimization |
Use next/image |
| External fonts |
Medium |
Layout shift, extra request |
Use next/font |
| Large initial bundle |
High |
Slow initial load |
Dynamic imports |
| No caching on static data |
Medium |
Unnecessary server load |
Add revalidate |
Using <a> instead of Link |
High |
Full page reload |
Use Link |
| No priority hints |
Low |
Delayed LCP |
Use priority prop |
Code Patterns
Images
// Good: next/image with sizing
import Image from 'next/image'
<Image
src="/avatar.jpg"
width={100}
height={100}
alt="Avatar"
priority // For above-fold images
/>
Fonts
// Good: next/font
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export default function RootLayout({ children }: { children: ReactNode }) {
return <html className={inter.className}>{children}</html>
}
Dynamic Imports
// Good: Dynamic import for heavy component
import dynamic from 'next/dynamic'
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <div>Loading...</div>,
ssr: false, // If client-only
})
Caching
// Good: Appropriate caching
export const revalidate = 3600 // Revalidate every hour
async function getData() {
const res = await fetch('https://api.example.com/data', {
next: { revalidate: 3600 } // or { revalidate: 0 } for no cache
})
return res.json()
}
Reference Index
| File |
Topics |
| images.md |
next/image, sizing, priority, formats |
| fonts.md |
next/font, Google fonts, local fonts |
| code-splitting.md |
Dynamic imports, route splitting |
| caching.md |
fetch options, ISR, revalidatePath |
| navigation.md |
Link component, prefetching, scroll |
Success Criteria
Performance is good when:
- All images use next/image with proper sizing
- Fonts loaded with next/font (no layout shift)
- Heavy components dynamically imported
- Static data cached appropriately (revalidate set)
- All internal links use Link component
- LCP < 2.5s, FID < 100ms, CLS < 0.1
1---2name: nextjs-performance3description: Next.js performance optimizations including next/image, next/font, dynamic imports, caching strategies, and bundle optimization. Use when optimizing Next.js apps for speed or Core Web Vitals.4---5
6# Next.js Performance
7
8Expert guidance for optimizing Next.js applications.
9
10## Quick Reference
11
12| Concern | Solution | Impact |
13|---------|----------|--------|
14| Images | next/image with sizing | CLS prevention, auto-optimization |
15| Fonts | next/font | No layout shift, self-hosted |
16| Heavy components | next/dynamic | Reduced initial bundle |
17| Data caching | fetch options (revalidate) | Reduced server load |
18| Client navigation | Link component | Instant transitions |
19| Bundle size | Tree shaking, no unused deps | Faster JS loading |
20
21## What Do You Need?
22
231. **Image optimization** - next/image usage, sizing, formats
242. **Font loading** - next/font, preloading
253. **Code splitting** - Dynamic imports, route splitting
264. **Caching** - ISR, revalidation, cache strategies
275. **Navigation** - Link usage, prefetching
28
29Specify a number or describe your performance concern.
30
31## Routing
32
33| Response | Reference to Read |
34|----------|-------------------|
35| 1, "image", "img", "optimization", "cls" | [images.md](./references/images.md) |
36| 2, "font", "layout shift", "typography" | [fonts.md](./references/fonts.md) |
37| 3, "dynamic", "import", "lazy", "split" | [code-splitting.md](./references/code-splitting.md) |
38| 4, "cache", "revalidate", "isr", "fetch" | [caching.md](./references/caching.md) |
39| 5, "navigation", "link", "prefetch" | [navigation.md](./references/navigation.md) |
40
41## Essential Principles
42
43**Optimize images**: Use next/image with width/height for all images. Prevents CLS and enables automatic optimization.
44
45**Self-host fonts**: Use next/font to eliminate requests to external font services and prevent layout shift.
46
47**Dynamic import heavy code**: Use next/dynamic for components that are heavy or not immediately visible.
48
49**Client-side navigation**: Use Link component for all internal links. Enables instant page transitions.
50
51**Cache strategically**: Use appropriate fetch caching (force-cache, no-store, revalidate) based on data freshness needs.
52
53## Common Performance Issues
54
55| Issue | Severity | Impact | Fix |
56|-------|----------|--------|-----|
57| Using `<img>` instead of next/image | High | CLS, no optimization | Use next/image |
58| External fonts | Medium | Layout shift, extra request | Use next/font |
59| Large initial bundle | High | Slow initial load | Dynamic imports |
60| No caching on static data | Medium | Unnecessary server load | Add revalidate |
61| Using `<a>` instead of Link | High | Full page reload | Use Link |
62| No priority hints | Low | Delayed LCP | Use priority prop |
63
64## Code Patterns
65
66### Images
67```typescript
68// Good: next/image with sizing
69import Image from 'next/image'
70
71<Image
72 src="/avatar.jpg"
73 width={100}
74 height={100}
75 alt="Avatar"
76 priority // For above-fold images
77/>
78```
79
80### Fonts
81```typescript
82// Good: next/font
83import { Inter } from 'next/font/google'
84
85const inter = Inter({ subsets: ['latin'] })
86
87export default function RootLayout({ children }: { children: ReactNode }) {
88 return <html className={inter.className}>{children}</html>
89}
90```
91
92### Dynamic Imports
93```typescript
94// Good: Dynamic import for heavy component
95import dynamic from 'next/dynamic'
96
97const HeavyChart = dynamic(() => import('./HeavyChart'), {
98 loading: () => <div>Loading...</div>,
99 ssr: false, // If client-only
100})
101```
102
103### Caching
104```typescript
105// Good: Appropriate caching
106export const revalidate = 3600 // Revalidate every hour
107
108async function getData() {
109 const res = await fetch('https://api.example.com/data', {
110 next: { revalidate: 3600 } // or { revalidate: 0 } for no cache
111 })
112 return res.json()
113}
114```
115
116## Reference Index
117
118| File | Topics |
119|------|--------|
120| [images.md](./references/images.md) | next/image, sizing, priority, formats |
121| [fonts.md](./references/fonts.md) | next/font, Google fonts, local fonts |
122| [code-splitting.md](./references/code-splitting.md) | Dynamic imports, route splitting |
123| [caching.md](./references/caching.md) | fetch options, ISR, revalidatePath |
124| [navigation.md](./references/navigation.md) | Link component, prefetching, scroll |
125
126## Success Criteria
127
128Performance is good when:
129- All images use next/image with proper sizing
130- Fonts loaded with next/font (no layout shift)
131- Heavy components dynamically imported
132- Static data cached appropriately (revalidate set)
133- All internal links use Link component
134- LCP < 2.5s, FID < 100ms, CLS < 0.1