I've shipped enough Next.js apps to know what actually matters. Here's my list.
1. Stop Making Everything a Client Component
Every 'use client' = more JavaScript shipped. I was putting it everywhere. Don't.
// This runs on server. Zero JS to client. export async function ProjectList() { const projects = await db.projects.findMany(); return ( <ul> {projects.map(p => <li key={p.id}>{p.name}</li>)} </ul> ); }
Only add 'use client' when you actually need interactivity. useState? onClick? Fine. Otherwise, keep it server.
2. next/image Is Not Optional
I used regular <img> tags on an early project. Lighthouse score: 45. Switched to next/image. Score: 89.
<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority // Above the fold? Use this. placeholder="blur" />
It's not just optimization — it's free performance.
3. Dynamic Imports for Heavy Stuff
Had a chart library adding 200KB to my bundle. Users saw it on one page.
const Chart = dynamic(() => import('./HeavyChart'), { loading: () => <div>Loading chart...</div>, ssr: false, });
Now it loads only when needed. Bundle size dropped. Users on slow connections thanked me (not literally, but spiritually).
4. Cache Like You Mean It
// Static data? Cache forever. fetch(url, { cache: 'force-cache' }) // Changes sometimes? Revalidate. fetch(url, { next: { revalidate: 3600 } }) // 1 hour // Real-time? Don't cache. fetch(url, { cache: 'no-store' })
I default to revalidate: 3600 and adjust from there.
5. Parallel Data Fetching
This is slow:
const user = await getUser(); const posts = await getPosts(); // Waits for user const comments = await getComments(); // Waits for posts
This is fast:
const [user, posts, comments] = await Promise.all([ getUser(), getPosts(), getComments(), ]);
If they don't depend on each other, fetch in parallel.
6. Analyze Your Bundle
npm install @next/bundle-analyzer ANALYZE=true npm run build
Found a 150KB dependency I imported once. Removed it. Bundle shrunk. Users happy.
The Result
TaskNotch and ZyMerge both score 90+ on Lighthouse. Not because I'm smart — because I stopped making dumb mistakes.
Your move.