Extract App Shell from static prefetches#94095
Conversation
Failing test suitesCommit: b48293d | About building and testing Next.js
Expand output● Cache Components Errors › Build With --prerender-debug › Dynamic Metadata - Error Route › should error the build for the correct reason when there is a cache components violation alongside dynamic metadata ● Cache Components Errors › Build With --prerender-debug › Dynamic Root › should error the build if cache components happens in the root (outside a Suspense) ● Cache Components Errors › Build With --prerender-debug › Error Attribution with Sync IO › Unguarded RSC with guarded Client sync IO › should error the build with a reason related dynamic data
Expand output● Cache Components Errors › Build With --prerender-debug › Dynamic Metadata - Error Route › should error the build for the correct reason when there is a cache components violation alongside dynamic metadata ● Cache Components Errors › Build With --prerender-debug › Dynamic Root › should error the build if cache components happens in the root (outside a Suspense) ● Cache Components Errors › Build With --prerender-debug › Error Attribution with Sync IO › Unguarded RSC with guarded Client sync IO › should error the build with a reason related dynamic data ● Cache Components Errors › Build With --prerender-debug › Inside ... truncated ... |
Adds support for extracting an App Shell from a more concrete prerender response. The server sends down a byte offset that represents the subset of the stream that corresponds to the reusable App Shell. This does _not_ yet implement shell extraction for per-segment prefetch responses. Implementing this adds an additional layer of complexity, because those responses are generated during a separate phase of the build process. We do intend to implement this, but it's a non-essential optimization that can come later. This also does not yet implement shell extraction from a navigation response (the Cached Navigations feature), though both features are based on essentially the same mechanism. I'm deferring this to a subsequent PR because some of the existing implementation needs to be rethought in light of the new App Shells based model; for example, the "static stage" boundary might not make sense to track separately from the App Shell. The main practical upshot of the PR is that if you have a fully statically prerendered page with no dynamic holes, that page's App Shell can now be fetched by the client without incurring any runtime server execution cost: the server will return the full static page, and the client will extract the App Shell from that concrete response.
Squashed server-only diff from: - #94044 Streaming prerender - #93801 Rewinding app shells This commit is a placeholder on the stack so we can develop and test the client-side rewinding integration that lands in the commit above. It gets regenerated from Janka's latest each time we re-sync; do not edit by hand. For now this uses only the fallback-stage branch as source because its app-render.tsx version supersedes streaming-prerender's (the smaller streaming-prerender files are byte-identical to fallback-stage's). Replaces the forceOmitParams hanging-promise mechanism from canary with the abort-before-params approach Janka builds on.
8fbc171 to
b48293d
Compare
Adds support for extracting an App Shell from a more concrete prerender response. The server sends down a byte offset that represents the subset of the stream that corresponds to the reusable App Shell.
This does not yet implement shell extraction for per-segment prefetch responses. Implementing this adds an additional layer of complexity, because those responses are generated during a separate phase of the build process. We do intend to implement this, but it's a non-essential optimization that can come later.
This also does not yet implement shell extraction from a navigation response (the Cached Navigations feature), though both features are based on essentially the same mechanism. I'm deferring this to a subsequent PR because some of the existing implementation needs to be rethought in light of the new App Shells based model; for example, the "static stage" boundary might not make sense to track separately from the App Shell.
The main practical upshot of the PR is that if you have a fully statically prerendered page with no dynamic holes, that page's App Shell can now be fetched by the client without incurring any runtime server execution cost: the server will return the full static page, and the client will extract the App Shell from that concrete response.