Commit Graph

17 Commits

Author SHA1 Message Date
Janka Uryga 46681d90f0 [PPF] Sync IO is only allowed in the dynamic stage (#95384)
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
2026-07-10 15:36:41 +00:00
Janka Uryga 3767dfae1f test: fork select tests on partialPrefetching (#95279)
Stopgap until we make this a proper part of the CI matrix
2026-06-29 22:43:34 +00:00
Josh Story ea3cad2848 Only error for sync IO after runtime in segments that would be runtime prefetched (#89979)
Stacked on #89984

When we initially implemented runtime prefetching we decided to make
sync IO that happens after runtime but before async IO an error. This is
similar to but more aggressive than the error for sync IO before runtime
data but is important because if you have sync IO before uncached IO and
we are runtime prefetching the page then we aren't going to get anything
useful from that prefetch but it might be very expensive.

The problem with the current implementation is that if you turn on
runtime prefetching for a Page segment then in practice the router will
only ever runtime prefetch that page segment but the sync IO validator
will error for sync IO before uncached IO anywhere in the route. This
makes adding runtime prefetching to leaf Segments much harder b/c you
have to address sync IO in the entire Segment stack.

This change updates the sync IO heuristic to only error in segments that
would be runtime prefetched and below. This way when you add runtime
prefetching to a segment you only have to true up the sync IO for the
part of the tree that has the changed behavior.

This PR only partially implements the intended semantics for runtime
prefetching validation of sync IO. One thing that will need to be done
in a follow up is handling sync IO in generateMetadata. In this case
while the functions are defined in layouts and pages they are
semantically always "owned" by the page itself. This means that while
the layout might not be runtime prefetchable and thus allow sync IO
after runtime data access the generateMetadata in that same layout might
not allow sync IO after runtime if there is a runtime prefetch config at
the page level or some layout higher. This will be done in a follow up
2026-02-18 14:49:30 -08:00
Hendrik Liebau 5ec4d7a4be [Cache Components] Prevent streaming fetch calls from hanging in dev (#89171)
With Cache Components enabled in development, fetches without an
explicit cache config were incorrectly routed through
`createCachedPrerenderResponse` during the cache filling phase due to
the `serverComponentsHmrCache` condition. This function awaits the
entire response before returning to the caller, which prevents
infinitely streaming responses from ever being read or aborted.

This is a regression that was introduced in #84088.

These fetches should be treated as dynamic and use
`createCachedDynamicResponse` instead, which returns immediately and
caches in the background with proper error handling. The fix adds
`isCacheableRevalidate` to the condition so only explicitly cacheable
fetches use the blocking path.

Additionally, the "Failed to set fetch cache" warning is now suppressed
when the request's abort signal was triggered, since aborting is
intentional.
2026-01-28 21:53:56 +01:00
Hendrik Liebau 36f50c5a11 Send dynamic validation errors to browser via WebSocket (#85818)
By sending the dynamic validation errors to the browser via WebSocket,
instead of rendering a validation outlet into the dynamic dev render
stream, we can avoid artificially delaying the spawned validation to
implicitly wait for the different chunks (static, runtime, and dynamic),
without blocking the dev render stream, and instead wait explicitly for
all chunks to accumulate.

Previously, we were using React's console replaying to get full fidelity
error stacks in the browser (including inspectable virtual server
modules). Now, we're using the same underlying mechanism by sending a
separate RSC stream through the WebSocket that contains only the errors.
In the browser, the received errors are then logged with
`console.error`, which also triggers that they're displayed in a
collapsed Redbox, as was the case before with the replaying.

---------

Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
2025-11-21 16:10:15 +01:00
Janka Uryga 3f4db01dbc [Cache Components] Discriminate static shell validation errors by type (#85747)
Prior to this change any "hole" in a prerender that would block the
shell was considered an error and you would be presented with a very
generic message explaining all the different ways you could have failed
this validation check.

With this change we use a new technique to validate the static shell
which can now tell the difference between waiting on uncached data or
runtime data. It also improves the heuristics around generateMetadata
and generateViewport errors.

Added new error pages for runtime sync IO and ensure we only validate
sync IO after runtime data if the page will be validating runtime
prefetches.

Restored the validation on HMR update so you can get feedback after
saving a new file.

---

We've also discovered that hanging inputs are not handled correctly.
Fixing this is non-trivial and will be done in a follow-up, so for now,
we're disabling the failing tests.

---------

Co-authored-by: Josh Story <story@hey.com>
Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
2025-11-20 17:13:37 +01:00
Janka Uryga 42b02b0771 [Cache Components] fix env labels in perf track test (#85132)
We updated the label for the Runtime stage to `Prefetchable` in #85076,
and #85111 wasn't rebased on top of that
2025-10-21 00:13:12 +02:00
Sebastian "Sebbie" Silbermann 2346cfd67d [test] Current behavior of dynamic APIs integration with React DevTools (#85111) 2025-10-20 23:04:53 +02:00
Sebastian "Sebbie" Silbermann caffa0d866 [test] Resolve elementByCSS and waitForElementByCSS once visible (#83301) 2025-09-03 09:47:35 +00:00
nextjs-bot 4b76801777 Upgrade React from 3d14fcf0-20250724 to 19baee81-20250725 (#82063)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-25 22:22:03 +00:00
nextjs-bot 4cf2da98ba Upgrade React from e9638c33-20250721 to 7513996f-20250722 (#81940)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-23 11:59:19 +00:00
Sebastian "Sebbie" Silbermann 16c53236a7 Configure url for responses from patched fetch like the original response.url (#81507)
The main config that was missing is enumerability which is relevant for showing properties in the Chrome performance track and inferring shorthands.
2025-07-11 00:05:27 +02:00
Sebastian "Sebbie" Silbermann df2c2a8cf0 [sourcemaps] Stop sending stackframes in third-party chunks (#81344) 2025-07-10 23:29:58 +02:00
Hendrik Liebau b5ced37273 Name patched fetch function fetch (#81499)
This ensures that `fetch` is shown in stack traces (in collapsed
ignore-listed frames), instead of `patched`.
2025-07-10 15:48:42 +02:00
nextjs-bot 9bbcfa2c14 Upgrade React from 5d87cd22-20250704 to a7a11657-20250708 (#81428)
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
2025-07-08 19:09:00 +00:00
Sebastian "Sebbie" Silbermann 76d9ab8e4e [test] Improve React performance track tests (#81359) 2025-07-07 16:04:53 +02:00
Sebastian "Sebbie" Silbermann 39f5d0f32c [test] Dedicate suite for React's Server Request performance track (#81312)
We're testing this here since framework integration via `filterStackTrace` determines what React uses to determine the name of the Performance entry.
2025-07-06 11:47:17 +02:00