Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of PPR client navigations
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.
- Loading branch information