rsnext/packages
Andrew Clark 0f746592d9
Initial implementation of PPR client navigations (#59725)
For a more detailed explanation of the algorithm, refer to the comments
in ppr-navigations.ts. Below is a high-level overview.

### Step 1: Render the prefetched data immediately

Immediately upon navigation, we construct a new Cache Node tree (i.e.
copy-on-write) that represents the optimistic result of a navigation,
using both the current Cache Node tree and data that was prefetched
prior to navigation.

At this point, we haven't yet received the navigation response from the
server. It could send back something completely different from the tree
that was prefetched — due to rewrites, default routes, parallel routes,
etc.

But in most cases, it will return the same tree that we prefetched, just
with the dynamic holes filled in. So we optimistically assume this will
happen, and accept that the real result could be arbitrarily different.

We'll reuse anything that was already in the previous tree, since that's
what the server does.

New segments (ones that don't appear in the old tree) are assigned an
unresolved promise. The data for these promises will be fulfilled later,
when the navigation response is received.

The tree can be rendered immediately after it is created. Any new trees
that do not have prefetch data will suspend during rendering, until the
dynamic data streams in.

### Step 2: Fill in the dynamic data as it streams in

When the dynamic data is received from the server, we can start filling
in the unresolved promises in the tree. All the pending promises that
were spawned by the navigation will be resolved, either with dynamic
data from the server, or `null` to indicate that the data is missing.

A `null` value will trigger a lazy fetch during render, which will then
patch up the tree using the same mechanism as the non-PPR implementation
(serverPatchReducer).

Usually, the server will respond with exactly the subset of data that
we're waiting for — everything below the nearest shared layout. But
technically, the server can return anything it wants.

This does _not_ create a new tree; it modifies the existing one in
place. Which means it must follow the Suspense rules of cache safety.

## To Do

Not all necessarily PR-blocking, since the status quo is that
navigations don't work at all when PPR is enabled

- [x] Figure out how to handle dynamic metadata. Need to switch from
prefetched metadata to final.
- [x] Some mistake related to parallel routes, need to look into failing
tests

Closes NEXT-1894
2023-12-20 13:24:40 -05:00
..
create-next-app v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
eslint-config-next v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
eslint-plugin-next v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
font v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next Initial implementation of PPR client navigations (#59725) 2023-12-20 13:24:40 -05:00
next-bundle-analyzer v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-codemod v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-env v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-mdx v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-plugin-storybook v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-polyfill-module v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-polyfill-nomodule v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
next-swc v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
react-dev-overlay v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
react-refresh-utils v14.0.5-canary.19 2023-12-19 23:19:49 +00:00
third-parties v14.0.5-canary.19 2023-12-19 23:19:49 +00:00