Commit Graph

2 Commits

Author SHA1 Message Date
James Anderson 48f4df28cb fix(pages-router): cancel deduped GSSP data waits (#2038) 2026-06-15 22:58:02 +01:00
James Anderson 26d1cc79bc fix(pages-router): dedupe in-flight _next/data fetches by URL (#1464) (#1684)
Concurrent `Router.push` calls (or back-to-back `<Link>` clicks) to the
same gSSP route each fired their own `_next/data/<id>/<page>.json` fetch.
The Next.js parity test asserts `hit: 1` after 4 rapid navigations to a
slow page; vinext was producing `hit: N`.

Add a module-scoped in-flight Promise cache keyed by the resolved data
URL, mirroring `fetchNextData()`'s `inflightCache` in
`packages/next/src/shared/lib/router/router.ts`. Concurrent callers share
one `fetch()` invocation and each receive a cloned Response. Entries
self-evict on settle so the next navigation re-fetches fresh.

The shared fetch deliberately ignores per-caller `AbortSignal`s: stale
navigations are already detected via `_navigationId` + `assertStillCurrent()`
checkpoints after the await, and aborting the shared request on behalf of
one superseded caller would destroy the dedup gain for every other
concurrent caller. Pre-await abort still surfaces so callers see the
documented `NavigationCancelledError` / `AbortError` when supersession
happened before the fetch was even attempted.

Wired into both `navigateClientData()` (the JSON fast path) and
`resolveMiddlewareDataRedirect()` (the soft-redirect probe).
2026-06-01 11:14:00 +01:00