From b77f77ee7d619fdf4d599df1cd0456292a33ac6e 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) 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. - 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`. > Benchmarked with console inside try-finally | Version | Ready | |-------------------------------------|---------| | Canary | 1185ms | | Delta | 896ms | | Delta Webpack vs Canary Webpack | -24.39% | | 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 | 13 +++++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/next/src/server/dev/hot-reloader-turbopack.ts b/packages/next/src/server/dev/hot-reloader-turbopack.ts index 3220403c2a1cb..b1afde773f350 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, @@ -494,7 +493,7 @@ export async function createHotReloaderTurbopack( ) ) const overlayMiddleware = getOverlayMiddleware(project) - const versionInfo: VersionInfo = await getVersionInfo( + const versionInfoPromise = getVersionInfo( isTestMode || opts.telemetry.isEnabled ) @@ -656,15 +655,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 + + const sync: SyncAction = { + action: HMR_ACTIONS_SENT_TO_BROWSER.SYNC, + errors, + warnings: [], + hash: '', + versionInfo, + } - sendToClient(client, sync) + 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 7de83535a7919..d6f49a3332e70 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' @@ -210,10 +209,16 @@ export async function getVersionInfo(enabled: boolean): Promise { try { installed = require('next/package.json').version - const registry = getRegistry() - const res = await fetch(`${registry}-/package/next/dist-tags`) + let res - if (!res.ok) return { installed, staleness: 'unknown' } + try { + // use NPM registry regardless user using Yarn + res = await fetch('https://registry.npmjs.org/-/package/next/dist-tags') + } catch { + // ignore fetch errors + } + + if (!res || !res.ok) return { installed, staleness: 'unknown' } const { latest, canary } = await res.json()