Skip to the solution
MediumFrontend5 min read

PPR vs ISR vs SSR — how do you pick the rendering strategy in Next 15?

654 views

The problem

Question presented to candidate: "You are designing a product page, a blog and an account dashboard. For each, would you use static with ISR, fully dynamic SSR, or Partial Prerendering, and why?"

What a strong answer should cover:

  • Static or ISR: content is the same for everyone and may be minutes or hours stale; fastest first byte, cheapest to serve.
  • Dynamic (SSR): content depends on the request and must be exact; every request renders, and the first byte waits for data unless you stream.
  • PPR: mostly shared content with a few personal parts; the shell is prerendered and the personal holes stream in the same response.
  • Streaming with loading.js or Suspense improves dynamic pages when PPR is not available.
  • In Next.js 16, PPR comes with Cache Components (cacheComponents: true), no longer an experimental flag; since 16.4 new create-next-app projects have it on, with partialPrefetching.

Clarifying questions expected:

  • "Which parts of the page differ per user?" — those decide whether the page needs holes.
  • "How quickly must edits appear?" — decides lifetime and on-demand revalidation.

Code / implementation expected: Optional — the configuration for each strategy.

  • ppr
  • isr
  • rendering

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

5 min read · 8 sections

Read the code

The three strategies side by side
// Blog post: static + ISR
export const revalidate = 3600;
export default async function Post() { /* shared content */ }

// Dashboard: dynamic, streamed
import { Suspense } from "react";
export default function Dashboard() {
  return <Suspense fallback={<Skeleton />}><Charts /></Suspense>; // Charts reads cookies()
}

// Product: PPR (next.config.ts: cacheComponents: true)
export default function Product() {
  return (
    <>
      <ProductDetails />                                  {/* 'use cache' inside */}
      <Suspense fallback={<p>Cart</p>}><CartCount /></Suspense>  {/* reads cookies() */}
    </>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 60 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

instrumentation.ts — what changed for observability in Next 15?

Continue