All Articles
PerformanceJun 5, 2026

Building Blazing-Fast Next.js

15 Apps

Deep dive into Server Components, Partial Prerendering, and the new caching model that separates good apps from great ones.

RG

Ravi Gupta

Founder · ERVFlow

Building Blazing-Fast Next.js 15 Apps

The Problem

Most Next.js apps ship slower than they should. Before v15, automatic caching was unpredictable — fetches were cached by default, invalidation was unclear, and client-side waterfalls crept in as apps grew. Teams spent days debugging stale data instead of shipping features.

The Solution

Next.js 15 hands control back to you. Explicit cache directives, Server Components that fetch their own data at the edge, and Partial Prerendering mean you can hit sub-200ms TTFB without fighting the framework.

The New Caching Model

Next.js 15 fundamentally rethinks caching. Gone are the days of aggressive automatic caching — now you opt in explicitly, giving you predictable, understandable behavior.

const data = await fetch('/api/posts', {
  cache: 'force-cache',
  next: { revalidate: 3600 }
});
Next.js 15 caching model — opt-in by default, predictable at scale
Next.js 15 caching model — opt-in by default, predictable at scale

Server Components First

Moving data fetching to the server eliminates client-side waterfalls. Each Server Component fetches its own data in parallel, reducing total load time dramatically.

Server Component data-flow — no client-side waterfalls
Server Component data-flow — no client-side waterfalls

Partial Prerendering

PPR lets you mix static shells with dynamic islands on the same page — the shell is served from the CDN in milliseconds while dynamic content streams in behind it.

Ship the shell, stream the rest." — The PPR mantra.

How to Migrate Your App

1

Audit your fetch calls

Run a global search for `fetch(` in your codebase. Add explicit `cache: 'force-cache'` or `cache: 'no-store'` to every call — no more implicit behavior.

2

Move data to Server Components

Identify every `useEffect` that fetches data and convert it to an async Server Component. Co-locate the fetch with the UI that needs it.

3

Enable Partial Prerendering

Add `experimental: { ppr: true }` to `next.config.ts` and wrap dynamic islands in `<Suspense>`. Your static shell ships from CDN instantly.

4

Measure with Lighthouse CI

Add Lighthouse CI to your GitHub Actions pipeline. Set performance budget gates to catch regressions before they reach production.

  • Use Server Components for all data fetching
  • Reserve Client Components for interactivity only
  • Enable `experimental.ppr` in next.config.ts
  • Profile with Chrome DevTools → Performance panel
  • Set correct Cache-Control headers on the edge

Key Takeaways

  • Next.js 15 uses opt-in caching — every fetch call needs an explicit cache directive
  • Server Components eliminate client-side data waterfalls by moving fetches to the server
  • PPR lets you mix static CDN-served shells with dynamic streaming content on one route
  • Lighthouse CI in your pipeline catches performance regressions before users see them
  • Profile with Chrome DevTools' Performance panel to find the biggest bottlenecks first

Frequently Asked Questions

PPR is marked experimental but stable enough for production with careful testing. Next.js 15.1+ has made it significantly more robust — many teams use it in production today.

Ready to build faster apps?

Try ERVFlow Free

Try ERVFlow Free
Next.jsReactWeb Perf
ERVFlow Newsletter

Stay ahead of the curve

Deep-dives on Next.js, AI, TypeScript, and DevOps — straight to your inbox.

© 2026ERVFlow· Made with using Next.js & Tailwind CSS

All rights reserved.