Skip to content

Commit eb0df3e

Browse files
committed
wait for pending modules
1 parent 2c5c916 commit eb0df3e

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ import {
197197
trackPendingChunkLoad,
198198
trackPendingImport,
199199
trackPendingModules,
200+
trackPendingModulesInRender,
200201
} from './module-loading/track-module-loading.external'
201202
import { isReactLargeShellError } from './react-large-shell-error'
202203
import type { GlobalErrorComponent } from '../../client/components/builtin/global-error'
@@ -2199,6 +2200,12 @@ async function renderToStream(
21992200
// This render might end up being used as a prospective render (if there's cache misses),
22002201
// so we need to set it up for filling caches.
22012202
const cacheSignal = new CacheSignal()
2203+
2204+
// If we encounter async modules that delay rendering, we'll also need to restart.
2205+
// TODO(restart-on-cache-miss): technically, we only need to wait for pending *server* modules here,
2206+
// but `trackPendingModules` doesn't distinguish between client and server.
2207+
trackPendingModulesInRender(cacheSignal)
2208+
22022209
const prerenderResumeDataCache = createPrerenderResumeDataCache()
22032210

22042211
requestStore.prerenderResumeDataCache = prerenderResumeDataCache

packages/next/src/server/app-render/module-loading/track-module-loading.external.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import {
66
trackPendingChunkLoad,
77
trackPendingImport,
88
trackPendingModules,
9+
trackPendingModulesInRender,
910
} from './track-module-loading.instance' with { 'turbopack-transition': 'next-shared' }
1011

11-
export { trackPendingChunkLoad, trackPendingImport, trackPendingModules }
12+
export {
13+
trackPendingChunkLoad,
14+
trackPendingImport,
15+
trackPendingModules,
16+
trackPendingModulesInRender,
17+
}

packages/next/src/server/app-render/module-loading/track-module-loading.instance.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,21 @@ export function trackPendingModules(cacheSignal: CacheSignal): void {
5252
// we can unsubscribe it.
5353
cacheSignal.cacheReady().then(unsubscribe)
5454
}
55+
56+
/**
57+
* Like `trackPendingModules`, but for use in a render, not a prerender.
58+
* See `CacheSignal#cacheReadyInRender` for an explanation.
59+
*/
60+
export function trackPendingModulesInRender(cacheSignal: CacheSignal): void {
61+
const moduleLoadingSignal = getModuleLoadingSignal()
62+
63+
// We can't just use `cacheSignal.trackRead(moduleLoadingSignal.cacheReady())`,
64+
// because we might start and finish multiple batches of module loads while waiting for caches,
65+
// and `moduleLoadingSignal.cacheReady()` would resolve after the first batch.
66+
// Instead, we'll keep notifying `cacheSignal` of each import/chunk-load.
67+
const unsubscribe = moduleLoadingSignal.subscribeToReads(cacheSignal)
68+
69+
// Later, when `cacheSignal` is no longer waiting for any caches (or imports that we've notified it of),
70+
// we can unsubscribe it.
71+
cacheSignal.cacheReadyInRender().then(unsubscribe)
72+
}

0 commit comments

Comments
 (0)