mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
9908328192
In, we #98278 attempted to fix runtime follow-ups for shells (if a static prefetch produced an insuffient shell). However, it introduced a regression in this scenario, where neither shells or prefetches use runtime data, so both of these links should use static prefetches: ```tsx <Link href="/static-param/one" prefetch={true} /> {/* Revealed later */} <Link href="/static-param/two" prefetch={true} /> ``` We'd correctly do a static prefetch for the first link. However, the second link would see a `RuntimeShell`-tier shell from the first link, and this check inside `isShellEntryEligibleForStaticAttempt` would fail (because `RuntimeShell` was now greater than `PPR`): https://github.com/vercel/next.js/blob/3c9d1ca77f7de845315dc166a57fc9f090c638b4/packages/next/src/client/components/segment-cache/scheduler.ts#L1261 as a result, `isShellEntryEligibleForStaticAttempt` would return `false`, and we would deopt to a runtime prefetch for the second link instead. Importantly, a page with `ensureStatic = "prefetch"`(which will be implemented in #98191) will currently be handled exactly like a page that did not use runtime data at build -- the client doesn't know that a page is meant to never use runtime requests at all, it's entirely based on the existing static hints/`needsRuntimeRequest` promise mechanism. So even if `/static/[slug]` sets `ensureStatic = "prefetch"`, we'd also do an unnecessary runtime prefetch for it even though we really shouldn't. Violating the `ensureStatic` contract seems worse than a missing runtime shell follow-up , because those can currently only happen if the shell starts using runtime data after a revalidation, and that's probably not a common scenario. So i'm partially reverting that change until we figure out how to handle this in a way that handles both cases correctly (i've attempted doing that, but it seems nontrivial) ### Testing We're now missing the runtime shell follow-up again, so tests related to that in `prefetch-app-shell-revalidation.test.ts` are marked as failing (but still assert on current behavior -- the follow-up failures can be reproduced by setting `REPRODUCE_MISSING_RUNTIME_SHELL_FOLLOW_UP=1`). Note that the runtime *prefetch* follow ups there work as expected -- those worked correctly even before #98278. I've also added some pretty comprehensive tests in `prefetch-static-shell.test.ts`. We now test the scenario that regressed, which we weren't doing before. We also test scenarios where we reveal multiple links, but some of them use runtime data in the prefetch, and some don't. There's some failures there related to the fact that we don't track runtime data accesses in shells and prefetches separately (revealed by `REPRODUCE_UNNECESSARY_RUNTIME_SHELL=1`), which will be addressed by #98129. I want to land that before doing anything else on this topic to avoid dealing with failures that are going to be fixed soon anyway. There's also one case (`REPRODUCE_UNNECESSARY_RUNTIME_PREFETCH=1`) which will not be fixed by it, and will need separate consideration.