mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
## Summary - Extract the invariant app-page handler into a shared runtime module while keeping each generated route entry as a small wrapper. - Keep the `interopDefault` binding in the route wrapper because the injected Turbopack metadata loader tree references it, and pass the same binding into the shared runtime. - Add a focused 14-route navigation benchmark with static metadata coverage. ## Why Turbopack gives every generated app-page entry a route-specific identity because its loader tree, page name, pathname, and module hooks are injected into the template. This caused the full app-page handler to be analyzed independently for every route. A clean native trace of the benchmark shows app-page analysis CPU falling from 1,619.39 ms across 14 route copies to 153.92 ms total across 14 small wrappers plus one shared runtime, a 90.5% reduction. Concurrency-corrected analysis time falls from 181.63 ms to 97.87 ms. The post-change fixture also includes a static icon to cover the injected metadata loader binding. ## Verification - `pnpm test-dev-turbo test/e2e/app-dir/metadata-icons/metadata-icons.test.ts` - `pnpm test-start-turbo test/production/adapter-config/adapter-config-export.test.ts` - `pnpm test-dev-turbo test/development/app-dir/app-page-entry-prefetch-performance/app-page-entry-prefetch-performance.test.ts` - `pnpm test-dev-webpack test/development/app-dir/app-page-entry-prefetch-performance/app-page-entry-prefetch-performance.test.ts` - Clean native reproduction: the metadata suite failed with `ReferenceError: interopDefault is not defined` before the binding fix and passed all 9 cases afterward. <!-- NEXT_JS_LLM -->
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
|
|
const backgroundRoutes = [
|
|
'/contacts',
|
|
'/emails',
|
|
'/templates',
|
|
'/workflows',
|
|
'/metrics',
|
|
'/logs',
|
|
'/api-keys',
|
|
'/domain',
|
|
'/webhooks',
|
|
'/integrations',
|
|
'/smtp',
|
|
'/settings',
|
|
]
|
|
|
|
describe('app-page entry prefetch performance', () => {
|
|
const traceEnv = process.env.NEXT_TURBOPACK_TRACING
|
|
? {
|
|
NEXT_TURBOPACK_TRACING: process.env.NEXT_TURBOPACK_TRACING,
|
|
...(process.env.NEXT_TURBOPACK_TRACING_PATH
|
|
? {
|
|
NEXT_TURBOPACK_TRACING_PATH:
|
|
process.env.NEXT_TURBOPACK_TRACING_PATH,
|
|
}
|
|
: {}),
|
|
}
|
|
: {}
|
|
|
|
const { next, isTurbopack } = nextTestSetup({
|
|
files: __dirname,
|
|
env: traceEnv,
|
|
skipStart: true,
|
|
})
|
|
|
|
beforeAll(async () => {
|
|
await next.start()
|
|
})
|
|
|
|
if (!isTurbopack) {
|
|
it('renders the route-specific app-page entry', async () => {
|
|
const $ = await next.render$('/dashboard/agent-inbox')
|
|
expect($('#agent-inbox').text()).toBe('agent-inbox')
|
|
})
|
|
|
|
it.skip('requires Turbopack tracing', () => {})
|
|
return
|
|
}
|
|
|
|
it('navigates to agent inbox with many visible route prefetches', async () => {
|
|
const browser = await next.browser('/dashboard')
|
|
|
|
expect(
|
|
await browser.eval(`document.querySelectorAll('nav a').length`)
|
|
).toBe(14)
|
|
expect(await browser.elementByCss('#overview').text()).toBe('overview')
|
|
expect(
|
|
await browser.eval(`document.querySelectorAll('link[rel="icon"]').length`)
|
|
).toBe(1)
|
|
|
|
// Link viewport prefetches are production-only in this checkout. Start the
|
|
// same endpoint compilation batch explicitly so the development benchmark
|
|
// deterministically models the source application's partial prefetching.
|
|
const batchStart = performance.now()
|
|
const backgroundCompilations = Promise.all(
|
|
backgroundRoutes.map(async (pathname) => {
|
|
const response = await next.fetch(`/dashboard${pathname}`)
|
|
expect(response.status).toBe(200)
|
|
await response.arrayBuffer()
|
|
})
|
|
)
|
|
|
|
await browser.eval(`window.__navigationStart = performance.now()`)
|
|
await browser.elementByCss('a[href="/dashboard/agent-inbox"]').click()
|
|
await browser.waitForElementByCss('#agent-inbox')
|
|
|
|
const elapsed = await browser.eval(
|
|
`performance.now() - window.__navigationStart`
|
|
)
|
|
await backgroundCompilations
|
|
const batchElapsed = performance.now() - batchStart
|
|
|
|
console.log(
|
|
`cold agent-inbox navigation under route compilation load: ${elapsed.toFixed(2)} ms`
|
|
)
|
|
console.log(
|
|
`12-route app-page compilation batch: ${batchElapsed.toFixed(2)} ms`
|
|
)
|
|
})
|
|
})
|