From ef83433c3ee3f12e2e18a375b776558ba6d97791 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 2 Jul 2024 02:16:22 +0900 Subject: [PATCH] perf: improve retrieving `versionInfo` on Turbo HMR (#67309) ### Why? Identified the bottleneck of Turbopack HMR, one of the reason is that we run `execSync` to get user's package manager and fetch their registry to get the latest & canary version of Next.js. This process was located at the initial of HMR, which could have been delayed to the initial of the error handling. ### How? - Remove getting user's package manager and just fetch from NPM regardless the user uses Yarn. - Used an async IIFE to await the promise of `getVerionInfo` value inside the synchronous `ws.handleUpgrade`. ### Benchmark > Benchmarked with console inside try-finally #### Webpack -- no cache | Version | Ready | |-------------------------------------|---------| | Canary | 1185ms | | Delta | 896ms | | Delta Webpack vs Canary Webpack | -24.39% | #### Turbopack | Version | Ready | |-------------------------------------|---------| | Canary | 1002ms | | Delta (Turbopack) | 509ms | | Delta Turbopack vs Canary Turbopack | -49.20% | --------- Co-authored-by: Jiachi Liu Co-authored-by: Tobias Koppers --- .../src/server/dev/hot-reloader-turbopack.ts | 23 +++++++++++-------- .../src/server/dev/hot-reloader-webpack.ts | 5 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/next/src/server/dev/hot-reloader-turbopack.ts b/packages/next/src/server/dev/hot-reloader-turbopack.ts index cf35475f86..49761d3999 100644 --- a/packages/next/src/server/dev/hot-reloader-turbopack.ts +++ b/packages/next/src/server/dev/hot-reloader-turbopack.ts @@ -41,7 +41,6 @@ import { } from '../lib/render-server' import { denormalizePagePath } from '../../shared/lib/page-path/denormalize-page-path' import { trace } from '../../trace' -import type { VersionInfo } from './parse-version-info' import { AssetMapper, type ChangeSubscriptions, @@ -504,7 +503,7 @@ export async function createHotReloaderTurbopack( ) ) const overlayMiddleware = getOverlayMiddleware(project) - const versionInfo: VersionInfo = await getVersionInfo( + const versionInfoPromise = getVersionInfo( isTestMode || opts.telemetry.isEnabled ) @@ -666,15 +665,19 @@ export async function createHotReloaderTurbopack( } } - const sync: SyncAction = { - action: HMR_ACTIONS_SENT_TO_BROWSER.SYNC, - errors, - warnings: [], - hash: '', - versionInfo, - } + ;(async function () { + const versionInfo = await versionInfoPromise - sendToClient(client, sync) + const sync: SyncAction = { + action: HMR_ACTIONS_SENT_TO_BROWSER.SYNC, + errors, + warnings: [], + hash: '', + versionInfo, + } + + sendToClient(client, sync) + })() }) }, diff --git a/packages/next/src/server/dev/hot-reloader-webpack.ts b/packages/next/src/server/dev/hot-reloader-webpack.ts index d6e5130c79..aea1a0fbe1 100644 --- a/packages/next/src/server/dev/hot-reloader-webpack.ts +++ b/packages/next/src/server/dev/hot-reloader-webpack.ts @@ -62,7 +62,6 @@ import { getProperError } from '../../lib/is-error' import ws from 'next/dist/compiled/ws' import { existsSync, promises as fs } from 'fs' import type { UnwrapPromise } from '../../lib/coalesced-function' -import { getRegistry } from '../../lib/helpers/get-registry' import { parseVersionInfo } from './parse-version-info' import type { VersionInfo } from './parse-version-info' import { isAPIRoute } from '../../lib/is-api-route' @@ -202,11 +201,11 @@ export async function getVersionInfo(enabled: boolean): Promise { try { installed = require('next/package.json').version - const registry = getRegistry() let res try { - res = await fetch(`${registry}-/package/next/dist-tags`) + // use NPM registry regardless user using Yarn + res = await fetch('https://registry.npmjs.org/-/package/next/dist-tags') } catch { // ignore fetch errors }