Partial Prefetching: Default to App Shell only
When Partial Prefetching is enabled (unstable_prefetch = 'partial'),
this changes the default behavior of Link to only prefetch the App
Shell of the target page, not the page data. Per-page data is only
prefetched if the Link's `prefetch` prop is set to `true`.
For dynamic/partially static pages, this roughly matches the pre-Cache
Components behavior: links to those pages never include page content,
only a reusable App Shell defined by `loading.tsx` (if defined).
For fully static pages, this is a significant behavior change: the
prior behavior of Next.js was to prefetch the entire static page,
regardless of whether `prefetch={true}` was set. As a default
behavior, this made sense for certain kinds of content-heavy sites,
like blogs, where most of the content is expected to be generated at
build time. These apps will now need to set the prefetch prop to
`true` to maintain the previous behavior.
The main motivation is to simplify the cost/performance model for
prefetching: rendering a Link is now "free" unless `prefetch={true}`
is set.
I've put "free" in quotes because even if `prefetch={true}` is not
set, Next.js will still prefetch a generic App Shell. However, this
App Shell only needs to be rendered once per filesystem route, as
opposed to once per link. So it's not prefetching in the usual sense
that is meant in the context of SPA-based web applications. It's more
like incremental bundle loading, except instead of loading just the
code for the route, we also load the generic UI.
To aid in incremental adoption of this feature, this also adds an
"eager" prefetch mode that can be set on any layout or page
(unstable_prefetch = 'unstable_eager'). When "eager" is set, every
Link to that route is assigned an implied `prefetch={true}`, restoring
the pre-Partial Prefetching behavior. Blog-like sites may find this
useful, but it's mostly intended to support migrating existing apps.
(For canary testers of Partial Prefetching, you can also enable eager
mode globally by setting `partialPrefetching: 'unstable_eager'`. This
is not recommended except for migration purposes, even for blog-like
sites.)