Next.js 15 App Router: Complete Performance Guide

Next.js 15 App Router: Complete Performance Guide
Your Next.js app is live. It looks great. But Lighthouse is giving you a 63, your LCP is slow, and your client is asking why competitors feel faster.
This guide shows how to fix that — with real-world architecture, not theory.
📌 Table of Contents
Performance Model
React Server Components
Partial Prerendering (PPR)
Streaming with Suspense
Image & Font Optimization
Code Splitting
Caching Strategy
Core Web Vitals
FAQ
Conclusion
⚙️ 1. Performance Model
Core principle:
Move as much work to the server as possible. Ship minimal JS to the client.
Architecture Shift
Component TypeBehaviorServer ComponentRuns on server, zero JSClient Component ('use client')Hydrated in browserRoute SegmentsStatic / Dynamic / PPR
💡 A page with 80% server components → drastically smaller JS bundle.
🧠 2. React Server Components (RSC)
Correct Mental Model
Page (Server)
→ Layout (Server)
→ DataFetcher (Server)
→ InteractiveWidget (Client)
→ StaticChild (Server ✅)
Example
export default async function DashboardPage() {
const stats = await db.getUserStats()
return (
<main>
<UserStats data={stats} /> // Server
<InteractiveChart data={stats} /> // Client
</main>
)
}
✔️ Server রাখো:
DB queries
API calls
Auth checks
Static UI
✔️ Client এ রাখো:
useState / useEffect
Event handlers
Browser APIs
⚡ 3. Partial Prerendering (PPR)
Biggest performance unlock in Next.js 15
Enable
experimental: {
ppr: true
}
Example
<>
<ProductInfo /> {/* Instant static */}
<Suspense fallback={<Skeleton />}>
<RecommendedItems /> {/* Streamed */}
</Suspense>
</>
Result:
⚡ Instant first paint
📈 Better LCP
🎯 Better UX
🌊 4. Streaming with Suspense
❌ Waterfall
const user = await getUser()
const orders = await getOrders()
✅ Parallel
await Promise.all([getUser(), getOrders()])
✅ Best UX
<Suspense fallback={<UserSkeleton />}><User /></Suspense>
<Suspense fallback={<OrderSkeleton />}><Orders /></Suspense>
💡 UI loads piece-by-piece instead of waiting.
🖼️ 5. Image & Font Optimization
next/image
<Image
src="/hero.jpg"
width={1200}
height={630}
priority
/>
✔ Auto optimization
✔ Lazy loading
✔ No CLS
next/font
const inter = Inter({
subsets: ['latin'],
display: 'swap'
})
✔ No external request
✔ No layout shift
📦 6. Code Splitting
const Editor = dynamic(() => import('./Editor'), {
loading: () => <Skeleton />,
ssr: false
})
Rule:
50KB component → lazy load it
🧩 7. Caching Strategy
Default (Next.js 15)
❗ No caching
Options
// ISR
fetch('/api', { next: { revalidate: 60 } })
// Tag-based
fetch('/api', { next: { tags: ['config'] } })
// No cache
fetch('/api', { cache: 'no-store' })
Decision Matrix
Data TypeStrategyReal-timeno-storeSemi-staticrevalidateStatictags
📊 8. Core Web Vitals
MetricTargetLCP< 2.5sCLS< 0.1INP< 200ms
Quick Wins ✅
priorityon hero imagesAlways width/height
Use Server Components
Use Suspense
Enable PPR
Analyze bundle
❓ FAQ
App Router use করবো?
✔ Yes — future-proof
RSC কি Redux replace করবে?
⚠️ Partial only
Expected gains?
📉 25–40% JS reduction
⚡ 30% LCP improvement
🚀 60% TTFB improvement
🧾 Conclusion
Performance = architecture discipline.
Golden Rules:
Default → Server Components
Use PPR
Stream UI
Optimize images
Be explicit with caching
Audit bundle regularly
🚀 CTA
Want 95+ Lighthouse scores consistently?
👉 Portfolio: https://sonjoybarman.xyz
👉 Let’s build something blazing fast.
Related services
I build SaaS, Next.js apps, and AI-ready marketing sites. Explore a focused offering or go straight to contact.
