mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
This PR makes Sync IO behavior more restrictive when `partialPrefetching` is on (either globally or for a page). - Previously, we allowed `await cookies(); Date.now()` in in segments that won't ever be runtime prefetched. This was achieved by separating segments into "early" and "late" stages and only erroring in the "early" ones. - After this PR, it will always be an error to do sync IO anywhere other than after `io()`/`connection()`/uncached IO (i.e. outside the Dynamic stage). We're doing this mainly because with `partialPrefetching`, `cookies()` resolves in App Shells, and sync IO causes a severe deopt in any prerender. `allow-runtime` also opts a route into `partialPrefetching`, which means that even the segments above the runtime prefetch boundary will need an App Shell and can't tolerate Sync IO. This PR removes all early/late stage separation, because we no longer need to vary the Sync IO behavior on the segment. Instead, we now pick whether a stageController should use - `SyncIOMode.AllowedInRuntimeOrDynamic` (legacy) - `SyncIOMode.AllowedInDynamic` (`partialPrefetching`) - `SyncIOMode.Untracked` if it needs to opt out I've removed the existing tests that asserted that sync IO is allowed in segments above the `allow-runtime` boundary. Instead, we check that sync io either errors (if partialPrefetching is on) or is allowed (if partialPrefetching is off) Closes NAR-855
31 lines
842 B
TypeScript
31 lines
842 B
TypeScript
import { cookies } from 'next/headers'
|
|
import { Fragment, Suspense } from 'react'
|
|
|
|
export const instant = { level: 'experimental-error' }
|
|
|
|
export default async function Page() {
|
|
return (
|
|
<main>
|
|
<p>
|
|
This page uses sync IO after awaiting cookies():
|
|
<SuspenseIfNotPartialPrefetching>
|
|
<SyncIOAfterCookies />
|
|
</SuspenseIfNotPartialPrefetching>
|
|
</p>
|
|
</main>
|
|
)
|
|
}
|
|
|
|
// Before partialPrefetching, cookies() is not allowed in shells,
|
|
// so it would fail instant validation unless wrapped in suspense.
|
|
// We're not interested in checking if cookies blocks,
|
|
// only in wheter the Sync IO after triggers an error.
|
|
const SuspenseIfNotPartialPrefetching = process.env.__NEXT_PARTIAL_PREFETCHING
|
|
? Fragment
|
|
: Suspense
|
|
|
|
async function SyncIOAfterCookies() {
|
|
await cookies()
|
|
return Date.now()
|
|
}
|