Skip to content

Commit aaf8a16

Browse files
authored
Remove prospective fallback prerenders (vercel#79304)
The prospective fallback prerenders, which ensured that a fallback shell could be prerendered without errors, were only needed when Dynamic IO was enabled and PPR was disabled. This scenario is no longer supported.
1 parent 0790b78 commit aaf8a16

10 files changed

Lines changed: 2 additions & 207 deletions

File tree

‎packages/next/src/build/index.ts‎

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ import {
193193
} from '../server/lib/experimental/ppr'
194194
import { FallbackMode, fallbackModeToFallbackField } from '../lib/fallback'
195195
import { RenderingMode } from './rendering-mode'
196-
import { getParamKeys } from '../server/request/fallback-params'
197196
import { InvariantError } from '../shared/lib/invariant-error'
198197
import { HTML_LIMITED_BOT_UA_RE_STRING } from '../shared/lib/router/utils/is-bot'
199198
import type { UseCacheTrackerKey } from './webpack/plugins/telemetry-plugin/use-cache-tracker-utils'
@@ -1613,10 +1612,6 @@ export default async function build(
16131612
const serverPropsPages = new Set<string>()
16141613
const additionalPaths = new Map<string, PrerenderedRoute[]>()
16151614
const staticPaths = new Map<string, PrerenderedRoute[]>()
1616-
const prospectiveRenders = new Map<
1617-
string,
1618-
{ page: string; originalAppPath: string }
1619-
>()
16201615
const appNormalizedPaths = new Map<string, string>()
16211616
const fallbackModes = new Map<string, FallbackMode>()
16221617
const appDefaultConfigs = new Map<string, AppSegmentConfig>()
@@ -1975,31 +1970,6 @@ export default async function build(
19751970

19761971
staticPaths.set(originalAppPath, [])
19771972
}
1978-
// As PPR isn't enabled for this route, if dynamic IO
1979-
// is enabled, and this is a dynamic route, we should
1980-
// complete a prospective render for the route so that
1981-
// we can use the fallback behavior. This lets us
1982-
// check that dynamic pages won't error when they
1983-
// enable PPR.
1984-
else if (config.experimental.dynamicIO && isDynamic) {
1985-
// If there's a page with a more specific render
1986-
// available, then we should skip the prospective
1987-
// render because it'll be done as a part of the
1988-
// that render to validate the dynamic state.
1989-
if (
1990-
// The existence of any prerendered routes when
1991-
// PPR is disabled means that the route has more
1992-
// specific prerendered routes that should be
1993-
// used for the diagnostic render anyways.
1994-
!workerResult.prerenderedRoutes ||
1995-
workerResult.prerenderedRoutes.length === 0
1996-
) {
1997-
prospectiveRenders.set(originalAppPath, {
1998-
page,
1999-
originalAppPath,
2000-
})
2001-
}
2002-
}
20031973

20041974
if (workerResult.prerenderedRoutes) {
20051975
staticPaths.set(
@@ -2718,28 +2688,6 @@ export default async function build(
27182688
})
27192689
})
27202690

2721-
// If the app does have dynamic IO enabled but does not have PPR
2722-
// enabled, then we need to perform a prospective render for all
2723-
// the dynamic pages to ensure that they won't error during
2724-
// rendering (due to a missing prelude).
2725-
for (const {
2726-
page,
2727-
originalAppPath,
2728-
} of prospectiveRenders.values()) {
2729-
defaultMap[page] = {
2730-
page: originalAppPath,
2731-
_ssgPath: page,
2732-
_fallbackRouteParams: getParamKeys(page),
2733-
// Prospective renders are only enabled for app pages.
2734-
_isAppDir: true,
2735-
// Prospective renders are only enabled when PPR is disabled.
2736-
_isRoutePPREnabled: false,
2737-
_isProspectiveRender: true,
2738-
// Dynamic IO does not currently support `dynamic === 'error'`.
2739-
_isDynamicError: false,
2740-
}
2741-
}
2742-
27432691
if (i18n) {
27442692
for (const page of [
27452693
...staticPages,

‎packages/next/src/export/routes/app-page.ts‎

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -30,58 +30,6 @@ import type { RequestLifecycleOpts } from '../../server/base-server'
3030
import type { AppSharedContext } from '../../server/app-render/app-render'
3131
import type { MultiFileWriter } from '../../lib/multi-file-writer'
3232

33-
export async function prospectiveRenderAppPage(
34-
req: MockedRequest,
35-
res: MockedResponse,
36-
page: string,
37-
pathname: string,
38-
query: NextParsedUrlQuery,
39-
fallbackRouteParams: FallbackRouteParams | null,
40-
partialRenderOpts: Omit<RenderOpts, keyof RequestLifecycleOpts>,
41-
sharedContext: AppSharedContext
42-
): Promise<undefined> {
43-
const afterRunner = new AfterRunner()
44-
45-
// If the page is `/_not-found`, then we should update the page to be `/404`.
46-
// UNDERSCORE_NOT_FOUND_ROUTE value used here, however we don't want to import it here as it causes constants to be inlined which we don't want here.
47-
if (page === '/_not-found/page') {
48-
pathname = '/404'
49-
}
50-
51-
try {
52-
await lazyRenderAppPage(
53-
new NodeNextRequest(req),
54-
new NodeNextResponse(res),
55-
pathname,
56-
query,
57-
fallbackRouteParams,
58-
{
59-
...partialRenderOpts,
60-
waitUntil: afterRunner.context.waitUntil,
61-
onClose: afterRunner.context.onClose,
62-
onAfterTaskError: afterRunner.context.onTaskError,
63-
},
64-
undefined,
65-
false,
66-
sharedContext
67-
)
68-
69-
// TODO(after): if we abort a prerender because of an error in an after-callback
70-
// we should probably communicate that better (and not log the error twice)
71-
await afterRunner.executeAfter()
72-
} catch (err) {
73-
if (!isDynamicUsageError(err)) {
74-
throw err
75-
}
76-
77-
// We should fail rendering if a client side rendering bailout
78-
// occurred at the page level.
79-
if (isBailoutToCSRError(err)) {
80-
throw err
81-
}
82-
}
83-
}
84-
8533
/**
8634
* Renders & exports a page associated with the /app directory
8735
*/

‎packages/next/src/export/worker.ts‎

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { createRequestResponseMocks } from '../server/lib/mock-request'
2626
import { isAppRouteRoute } from '../lib/is-app-route-route'
2727
import { hasNextSupport } from '../server/ci-info'
2828
import { exportAppRoute } from './routes/app-route'
29-
import { exportAppPage, prospectiveRenderAppPage } from './routes/app-page'
29+
import { exportAppPage } from './routes/app-page'
3030
import { exportPagesPage } from './routes/pages'
3131
import { getParams } from './helpers/get-params'
3232
import { createIncrementalCache } from './helpers/create-incremental-cache'
@@ -104,10 +104,6 @@ async function exportPageImpl(
104104
// the renderOpts.
105105
_isRoutePPREnabled: isRoutePPREnabled,
106106

107-
// If this is a prospective render, we don't actually want to persist the
108-
// result, we just want to use it to error the build if there's a problem.
109-
_isProspectiveRender: isProspectiveRender = false,
110-
111107
// Configure the rendering of the page not to throw if an empty static shell
112108
// is generated while rendering using PPR.
113109
_doNotThrowOnEmptyStaticShell: doNotThrowOnEmptyStaticShell = false,
@@ -287,21 +283,6 @@ async function exportPageImpl(
287283
buildId: input.buildId,
288284
}
289285

290-
// If this is a prospective render, don't return any metrics or revalidate
291-
// timings as we aren't persisting this render (it was only to error).
292-
if (isProspectiveRender) {
293-
return prospectiveRenderAppPage(
294-
req,
295-
res,
296-
page,
297-
pathname,
298-
query,
299-
fallbackRouteParams,
300-
renderOpts,
301-
sharedContext
302-
)
303-
}
304-
305286
return exportAppPage(
306287
req,
307288
res,

‎packages/next/src/server/config-schema.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ const zExportMap: zod.ZodType<ExportPathMap> = z.record(
4141
_isAppDir: z.boolean().optional(),
4242
_isDynamicError: z.boolean().optional(),
4343
_isRoutePPREnabled: z.boolean().optional(),
44-
_isProspectiveRender: z.boolean().optional(),
4544
_doNotThrowOnEmptyStaticShell: z.boolean().optional(),
4645
})
4746
)

‎packages/next/src/server/config-shared.ts‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -743,16 +743,6 @@ export type ExportPathMap = {
743743
*/
744744
_isRoutePPREnabled?: boolean
745745

746-
/**
747-
* When true, it indicates that this page is being rendered in an attempt to
748-
* discover if the page will be safe to generate with PPR. This is only
749-
* enabled when the app has `experimental.dynamicIO` enabled but does not
750-
* have `experimental.ppr` enabled.
751-
*
752-
* @internal
753-
*/
754-
_isProspectiveRender?: boolean
755-
756746
/**
757747
* When true, it indicates that the diagnostic render for this page is
758748
* disabled. This is only used when the app has `experimental.ppr` and

‎packages/next/src/server/request/fallback-params.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getRouteRegex } from '../../shared/lib/router/utils/route-regex'
33

44
export type FallbackRouteParams = ReadonlyMap<string, string>
55

6-
export function getParamKeys(page: string) {
6+
function getParamKeys(page: string) {
77
const pattern = getRouteRegex(page)
88
const matcher = getRouteMatcher(pattern)
99

‎test/e2e/app-dir/dynamic-io-errors/dynamic-io-errors.prospective-fallback.test.ts‎

Lines changed: 0 additions & 54 deletions
This file was deleted.

‎test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/app/blog/[slug]/page.jsx‎

Lines changed: 0 additions & 4 deletions
This file was deleted.

‎test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/app/layout.jsx‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/next.config.js‎

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)