Question presented to candidate: "A product page is mostly static but shows a personalised cart badge. Historically you had to choose static or dynamic for the whole route. How does Partial Prerendering change that?"
What a strong answer should cover:
- The problem it solves: rendering strategy was a per-route decision. One personalised element forced the entire page to be dynamic, losing the CDN-cached instant response.
- PPR splits a single route: a static shell is prerendered at build time and served instantly from the edge, with holes where dynamic content will go.
- The dynamic parts stream in afterwards, filling the holes — one HTTP response, progressively completed.
- Suspense boundaries define the holes. Anything inside a boundary that uses dynamic APIs becomes a hole; everything else is prerendered into the shell.
- The fallback you write becomes what is baked into the static shell, so it should be a real skeleton rather than a blank space.
- It builds directly on streaming SSR and Suspense — the same mechanism, applied at the route level.
- The user-visible benefit: near-instant first paint from cache with personalised content arriving moments later, rather than waiting for the slowest data before anything appears.
- Status matters: PPR has been an experimental, opt-in Next.js feature rather than a default, so claiming it as standard is a mistake.
Clarifying questions expected:
- "How much of the page is genuinely personalised?" — if most of it is, PPR buys little.
- "Which Next.js version, and is the flag enabled?"
Code / implementation expected: Optional. Showing where the Suspense boundary goes is the substance.