diff --git a/packages/nuxt/src/app/plugins/browser-devtools-timing.client.ts b/packages/nuxt/src/app/plugins/browser-devtools-timing.client.ts new file mode 100644 index 0000000000..c740238880 --- /dev/null +++ b/packages/nuxt/src/app/plugins/browser-devtools-timing.client.ts @@ -0,0 +1,42 @@ +import { defineNuxtPlugin } from '../nuxt' + +export default defineNuxtPlugin({ + name: 'nuxt:browser-devtools-timing', + enforce: 'pre', + setup (nuxtApp) { + nuxtApp.hooks.beforeEach((event) => { + // @ts-expect-error __startTime is not a public API + event.__startTime = performance.now() + }) + + // After each + nuxtApp.hooks.afterEach((event) => { + performance.measure(event.name, { + // @ts-expect-error __startTime is not a public API + start: event.__startTime, + detail: { + devtools: { + dataType: 'track-entry', + track: 'nuxt', + color: 'tertiary-dark', + } satisfies ExtensionTrackEntryPayload, + }, + }) + }) + }, +}) + +type DevToolsColor = + 'primary' | 'primary-light' | 'primary-dark' | + 'secondary' | 'secondary-light' | 'secondary-dark' | + 'tertiary' | 'tertiary-light' | 'tertiary-dark' | + 'error' + +interface ExtensionTrackEntryPayload { + dataType?: 'track-entry' // Defaults to "track-entry" + color?: DevToolsColor // Defaults to "primary" + track: string // Required: Name of the custom track + trackGroup?: string // Optional: Group for organizing tracks + properties?: [string, string][] // Key-value pairs for detailed view + tooltipText?: string // Short description for tooltip +} diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 12ad094adc..9b92f8ac11 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -548,6 +548,12 @@ async function initNuxt (nuxt: Nuxt) { addPlugin(resolve(nuxt.options.appDir, 'plugins/debug')) } + // Add experimental Chrome devtools timings support + // https://developer.chrome.com/docs/devtools/performance/extension + if (nuxt.options.experimental.browserDevtoolsTiming) { + addPlugin(resolve(nuxt.options.appDir, 'plugins/browser-devtools-timing.client')) + } + for (const [key, options] of modulesToInstall) { await installModule(key, options) } diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index 506ddb6481..726ee551af 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -417,5 +417,14 @@ export default defineUntypedSchema({ return val ?? ((await get('future') as Record).compatibilityVersion === 4) }, }, + + /** + * Enable timings for Nuxt application hooks in the performance panel of Chromium-based browsers. + * + * @see [the Chrome DevTools extensibility API](https://developer.chrome.com/docs/devtools/performance/extension#tracks) + */ + browserDevtoolsTiming: { + $resolve: async (val, get) => val ?? await get('dev'), + }, }, })