Skip to content

Commit 2ed06f0

Browse files
lubieowocegnoff
andauthored
label as Prefetch/Prefetchable depending on prefetch config (#85076)
Tweaks the environment label logic to only use label things as `Prefetch` if there's a runtime prefetch config. If there's none, we label it as `Prefetchable` instead. --------- Co-authored-by: Josh Story <[email protected]>
1 parent 899b473 commit 2ed06f0

File tree

36 files changed

+816
-230
lines changed

36 files changed

+816
-230
lines changed

packages/next/src/server/app-render/app-render.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ import { createPromiseWithResolvers } from '../../shared/lib/promise-with-resolv
212212
import { ImageConfigContext } from '../../shared/lib/image-config-context.shared-runtime'
213213
import { imageConfigDefault } from '../../shared/lib/image-config'
214214
import { RenderStage, StagedRenderingController } from './staged-rendering'
215+
import { anySegmentHasRuntimePrefetchEnabled } from './staged-validation'
215216

216217
export type GetDynamicParamFromSegment = (
217218
// [slug] / [[slug]] / [...slug]
@@ -2767,7 +2768,16 @@ async function renderWithRestartOnCacheMissInDev(
27672768
getPayload: (requestStore: RequestStore) => Promise<RSCPayload>,
27682769
onError: (error: unknown) => void
27692770
) {
2770-
const { htmlRequestId, renderOpts, requestId } = ctx
2771+
const {
2772+
htmlRequestId,
2773+
renderOpts,
2774+
requestId,
2775+
componentMod: {
2776+
routeModule: {
2777+
userland: { loaderTree },
2778+
},
2779+
},
2780+
} = ctx
27712781
const {
27722782
clientReferenceManifest,
27732783
ComponentMod,
@@ -2776,6 +2786,9 @@ async function renderWithRestartOnCacheMissInDev(
27762786
} = renderOpts
27772787
assertClientReferenceManifest(clientReferenceManifest)
27782788

2789+
const hasRuntimePrefetch =
2790+
await anySegmentHasRuntimePrefetchEnabled(loaderTree)
2791+
27792792
// If the render is restarted, we'll recreate a fresh request store
27802793
let requestStore: RequestStore = initialRequestStore
27812794

@@ -2785,8 +2798,7 @@ async function renderWithRestartOnCacheMissInDev(
27852798
case RenderStage.Static:
27862799
return 'Prerender'
27872800
case RenderStage.Runtime:
2788-
// TODO: only label as "Prefetch" if the page has a `prefetch` config.
2789-
return 'Prefetch'
2801+
return hasRuntimePrefetch ? 'Prefetch' : 'Prefetchable'
27902802
case RenderStage.Dynamic:
27912803
return 'Server'
27922804
default:
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { getLayoutOrPageModule } from '../lib/app-dir-module'
2+
import type { LoaderTree } from '../lib/app-dir-module'
3+
import { parseLoaderTree } from '../../shared/lib/router/utils/parse-loader-tree'
4+
import type { AppSegmentConfig } from '../../build/segment-config/app/app-segment-config'
5+
6+
export async function anySegmentHasRuntimePrefetchEnabled(
7+
tree: LoaderTree
8+
): Promise<boolean> {
9+
const { mod: layoutOrPageMod } = await getLayoutOrPageModule(tree)
10+
11+
// TODO(restart-on-cache-miss): Does this work correctly for client page/layout modules?
12+
const prefetchConfig = layoutOrPageMod
13+
? (layoutOrPageMod as AppSegmentConfig).unstable_prefetch
14+
: undefined
15+
/** Whether this segment should use a runtime prefetch instead of a static prefetch. */
16+
const hasRuntimePrefetch = prefetchConfig?.mode === 'runtime'
17+
if (hasRuntimePrefetch) {
18+
return true
19+
}
20+
21+
const { parallelRoutes } = parseLoaderTree(tree)
22+
for (const parallelRouteKey in parallelRoutes) {
23+
const parallelRoute = parallelRoutes[parallelRouteKey]
24+
const hasChildRuntimePrefetch =
25+
await anySegmentHasRuntimePrefetchEnabled(parallelRoute)
26+
if (hasChildRuntimePrefetch) {
27+
return true
28+
}
29+
}
30+
31+
return false
32+
}

0 commit comments

Comments
 (0)