Partial Fallback Prerendering (#68958)
This work introduces the new concept of **Partial Fallback Prerendering
(PFPR)**.
Traditionally, when a dynamic page needed to be routed to that wasn't
pregenerated, it required a render to generate even the first few bytes
of the static page itself. This resulted in slow page loads for pages
not frequently visited and a reduced Time to First Byte (TTFB) score on
Core Web Vitals (CWV).
PFPR takes advantage of the new systems of Partial Prerendering (PPR)
that allows the application to suspend at different points mid-render,
and resume it later. We mark any unknown parameter access as dynamic
access, and suspend the rendering up to the next suspense boundaries at
those points. Under ideal conditions (correctly placed `<Suspense />`
boundaries or `loading.jsx` files) this generates a static shell that
can be served to users as soon as the request hits Next.js, right out of
the static cache. This minimizes the TTFB for all requests, dynamic or
not for those pages that enable PPR. For example, the following page
would create a usable shell:
```jsx
// /app/users/[userID]/page.jsx
import { Suspense } from 'react'
function Profile({ params }) {
const { userID } = params
return <div>Hello {userID}!</div>
}
export default function ProfilePage({ params }) {
return (
<div>
<h1>User Profile</h1>
<Suspense fallback="Loading...">
<Profile params={params} />
</Suspense>
</div>
)
}
```
Due to the way that suspense works within React components, access of
params within the root page component would cause the whole page to
suspend. Thankfully, that's where the `loading.jsx` comes in handy.
Adding a `loading.jsx` at a segment will automatically wrap the
`page.jsx` with a suspense boundary, setting the contents of the root
`loading.jsx` as the fallback component to use for it. This lets you
maintain your existing style of accessing parameters at the root of the
components while also taking advantage of PFPR.
To enable this feature, you first need to enable both PPR and PFPR:
```js
module.exports = {
experimental: {
ppr: true,
pprFallbacks: true,
}
}
```
Once PFPR has stabilized with hosting providers, the experimental flag
will go away and it will become the default with the PPR flag.