From 261dc194f52e52916b642645261e4c0a841ebd12 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:39:47 -0700 Subject: [PATCH 1/8] Remove unused PerformanceObserver --- src/compiler/performanceCore.ts | 42 ++++----------------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index a214ced47ef2c..5c7a3dd5339f2 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -10,7 +10,6 @@ export interface PerformanceHooks { /** Indicates whether we should write native performance events */ shouldWriteNativeEvents: boolean; performance: Performance; - PerformanceObserver: PerformanceObserverConstructor; } /** @internal */ @@ -23,53 +22,24 @@ export interface Performance { timeOrigin: number; } -/** @internal */ -export interface PerformanceEntry { - name: string; - entryType: string; - startTime: number; - duration: number; -} - -/** @internal */ -export interface PerformanceObserverEntryList { - getEntries(): PerformanceEntryList; - getEntriesByName(name: string, type?: string): PerformanceEntryList; - getEntriesByType(type: string): PerformanceEntryList; -} - -/** @internal */ -export interface PerformanceObserver { - disconnect(): void; - observe(options: { entryTypes: readonly ("mark" | "measure")[]; }): void; -} - -/** @internal */ -export type PerformanceObserverConstructor = new (callback: (list: PerformanceObserverEntryList, observer: PerformanceObserver) => void) => PerformanceObserver; -/** @internal */ -export type PerformanceEntryList = PerformanceEntry[]; - // Browser globals for the Web Performance User Timings API declare const performance: Performance | undefined; -declare const PerformanceObserver: PerformanceObserverConstructor | undefined; // eslint-disable-next-line @typescript-eslint/naming-convention -function hasRequiredAPI(performance: Performance | undefined, PerformanceObserver: PerformanceObserverConstructor | undefined) { +function hasRequiredAPI(performance: Performance | undefined) { return typeof performance === "object" && typeof performance.timeOrigin === "number" && typeof performance.mark === "function" && typeof performance.measure === "function" && typeof performance.now === "function" && typeof performance.clearMarks === "function" && - typeof performance.clearMeasures === "function" && - typeof PerformanceObserver === "function"; + typeof performance.clearMeasures === "function"; } function tryGetWebPerformanceHooks(): PerformanceHooks | undefined { if ( typeof performance === "object" && - typeof PerformanceObserver === "function" && - hasRequiredAPI(performance, PerformanceObserver) + hasRequiredAPI(performance) ) { return { // For now we always write native performance events when running in the browser. We may @@ -77,7 +47,6 @@ function tryGetWebPerformanceHooks(): PerformanceHooks | undefined { // in the browser also slow down compilation. shouldWriteNativeEvents: true, performance, - PerformanceObserver, }; } } @@ -85,13 +54,12 @@ function tryGetWebPerformanceHooks(): PerformanceHooks | undefined { function tryGetNodePerformanceHooks(): PerformanceHooks | undefined { if (isNodeLikeSystem()) { try { - const { performance, PerformanceObserver } = require("perf_hooks") as typeof import("perf_hooks"); - if (hasRequiredAPI(performance, PerformanceObserver)) { + const { performance } = require("perf_hooks") as typeof import("perf_hooks"); + if (hasRequiredAPI(performance)) { return { // By default, only write native events when generating a cpu profile or using the v8 profiler. shouldWriteNativeEvents: false, performance, - PerformanceObserver, }; } } From 53b3e3be9dd907d730948655436f3297a1a60278 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:11:18 -0700 Subject: [PATCH 2/8] Restructure performanceCore --- src/compiler/performance.ts | 4 +- src/compiler/performanceCore.ts | 100 +++++++++++++++++--------------- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 1605fa5e3562a..ea817ef289da2 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -180,13 +180,13 @@ export function enable(system: System = sys) { if (!enabled) { enabled = true; perfHooks ||= tryGetNativePerformanceHooks(); - if (perfHooks) { + if (perfHooks?.performance) { timeorigin = perfHooks.performance.timeOrigin; // NodeJS's Web Performance API is currently slower than expected, but we'd still like // to be able to leverage native trace events when node is run with either `--cpu-prof` // or `--prof`, if we're running with our own `--generateCpuProfile` flag, or when // running in debug mode (since its possible to generate a cpu profile while debugging). - if (perfHooks.shouldWriteNativeEvents || system?.cpuProfilingEnabled?.() || system?.debugMode) { + if (perfHooks.isGlobal || system?.cpuProfilingEnabled?.() || system?.debugMode) { performanceImpl = perfHooks.performance; } } diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 5c7a3dd5339f2..79007c15bf54a 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -7,72 +7,80 @@ import { /** @internal */ export interface PerformanceHooks { - /** Indicates whether we should write native performance events */ - shouldWriteNativeEvents: boolean; - performance: Performance; + isGlobal: boolean; + performance?: Performance; + performanceTime?: PerformanceTime; } /** @internal */ -export interface Performance { +export interface PerformanceTime { + now(): number; + timeOrigin: number; +} + +/** @internal */ +export interface PerformanceMarkAndMeasure { mark(name: string): void; measure(name: string, startMark?: string, endMark?: string): void; clearMeasures(name?: string): void; clearMarks(name?: string): void; - now(): number; - timeOrigin: number; } +/** @internal */ +export interface Performance extends PerformanceTime, PerformanceMarkAndMeasure {} + // Browser globals for the Web Performance User Timings API declare const performance: Performance | undefined; -// eslint-disable-next-line @typescript-eslint/naming-convention -function hasRequiredAPI(performance: Performance | undefined) { - return typeof performance === "object" && - typeof performance.timeOrigin === "number" && - typeof performance.mark === "function" && - typeof performance.measure === "function" && - typeof performance.now === "function" && - typeof performance.clearMarks === "function" && - typeof performance.clearMeasures === "function"; -} - -function tryGetWebPerformanceHooks(): PerformanceHooks | undefined { - if ( - typeof performance === "object" && - hasRequiredAPI(performance) - ) { - return { - // For now we always write native performance events when running in the browser. We may - // make this conditional in the future if we find that native web performance hooks - // in the browser also slow down compilation. - shouldWriteNativeEvents: true, - performance, - }; - } -} - -function tryGetNodePerformanceHooks(): PerformanceHooks | undefined { +function tryGetPerformance() { + // Try Node first; Node 16+ have the performance global but we want consistent behavior. if (isNodeLikeSystem()) { try { const { performance } = require("perf_hooks") as typeof import("perf_hooks"); - if (hasRequiredAPI(performance)) { - return { - // By default, only write native events when generating a cpu profile or using the v8 profiler. - shouldWriteNativeEvents: false, - performance, - }; - } + return { performance, isGlobal: false }; } catch { // ignore errors } } + + if (typeof performance === "object") { + return { performance, isGlobal: true }; + } + + return undefined; +} + +function tryGetPerformanceHooks(): PerformanceHooks | undefined { + const p = tryGetPerformance(); + if (!p) return undefined; + const { performance, isGlobal } = p; + + const hooks: PerformanceHooks = { + isGlobal, + performance: undefined, + performanceTime: undefined, + }; + + if (typeof performance.timeOrigin === "number" && typeof performance.now === "function") { + hooks.performanceTime = performance; + } + + if ( + hooks.performanceTime && + typeof performance.mark === "function" && + typeof performance.measure === "function" && + typeof performance.clearMarks === "function" && + typeof performance.clearMeasures === "function" + ) { + hooks.performance = performance; + } + + return hooks; } -// Unlike with the native Map/Set 'tryGet' functions in corePublic.ts, we eagerly evaluate these -// since we will need them for `timestamp`, below. -const nativePerformanceHooks = tryGetWebPerformanceHooks() || tryGetNodePerformanceHooks(); -const nativePerformance = nativePerformanceHooks?.performance; +const nativePerformanceHooks = tryGetPerformanceHooks(); +const nativePerformanceTime = nativePerformanceHooks?.performanceTime; /** @internal */ export function tryGetNativePerformanceHooks() { @@ -84,6 +92,4 @@ export function tryGetNativePerformanceHooks() { * * @internal */ -export const timestamp = nativePerformance ? () => nativePerformance.now() : - Date.now ? Date.now : - () => +(new Date()); +export const timestamp = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now; From e156fda77cecf6d822de3067a880973daa4cda25 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:31:45 -0700 Subject: [PATCH 3/8] Put global first again for no behavior change --- src/compiler/performanceCore.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 79007c15bf54a..db5183ea547ca 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -33,7 +33,10 @@ export interface Performance extends PerformanceTime, PerformanceMarkAndMeasure declare const performance: Performance | undefined; function tryGetPerformance() { - // Try Node first; Node 16+ have the performance global but we want consistent behavior. + if (typeof performance === "object") { + return { performance, isGlobal: true }; + } + if (isNodeLikeSystem()) { try { const { performance } = require("perf_hooks") as typeof import("perf_hooks"); @@ -44,10 +47,6 @@ function tryGetPerformance() { } } - if (typeof performance === "object") { - return { performance, isGlobal: true }; - } - return undefined; } From 2511c665bd872d6446c6a224c37695ea0d7e41f9 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:33:01 -0700 Subject: [PATCH 4/8] simplify types --- src/compiler/performanceCore.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index db5183ea547ca..28ad222f692c6 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -19,16 +19,13 @@ export interface PerformanceTime { } /** @internal */ -export interface PerformanceMarkAndMeasure { +export interface Performance extends PerformanceTime { mark(name: string): void; measure(name: string, startMark?: string, endMark?: string): void; clearMeasures(name?: string): void; clearMarks(name?: string): void; } -/** @internal */ -export interface Performance extends PerformanceTime, PerformanceMarkAndMeasure {} - // Browser globals for the Web Performance User Timings API declare const performance: Performance | undefined; From 34b13bae79dc6503b5d35f3e7328d9a01812078f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 21 Mar 2024 20:56:03 -0700 Subject: [PATCH 5/8] Try global second --- src/compiler/performanceCore.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 28ad222f692c6..581a6d43f718f 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -30,10 +30,6 @@ export interface Performance extends PerformanceTime { declare const performance: Performance | undefined; function tryGetPerformance() { - if (typeof performance === "object") { - return { performance, isGlobal: true }; - } - if (isNodeLikeSystem()) { try { const { performance } = require("perf_hooks") as typeof import("perf_hooks"); @@ -44,6 +40,10 @@ function tryGetPerformance() { } } + if (typeof performance === "object") { + return { performance, isGlobal: true }; + } + return undefined; } @@ -89,3 +89,5 @@ export function tryGetNativePerformanceHooks() { * @internal */ export const timestamp = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now; + +console.log(timestamp === Date.now); From a5e44e643942bba971930b95fe3f49e650fa45e7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:16:39 -0700 Subject: [PATCH 6/8] Restore comments and name, remove log --- src/compiler/performance.ts | 2 +- src/compiler/performanceCore.ts | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index ea817ef289da2..40b333041e636 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -186,7 +186,7 @@ export function enable(system: System = sys) { // to be able to leverage native trace events when node is run with either `--cpu-prof` // or `--prof`, if we're running with our own `--generateCpuProfile` flag, or when // running in debug mode (since its possible to generate a cpu profile while debugging). - if (perfHooks.isGlobal || system?.cpuProfilingEnabled?.() || system?.debugMode) { + if (perfHooks.shouldWriteNativeEvents || system?.cpuProfilingEnabled?.() || system?.debugMode) { performanceImpl = perfHooks.performance; } } diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 581a6d43f718f..7079f581361bf 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -7,7 +7,7 @@ import { /** @internal */ export interface PerformanceHooks { - isGlobal: boolean; + shouldWriteNativeEvents: boolean; performance?: Performance; performanceTime?: PerformanceTime; } @@ -32,8 +32,9 @@ declare const performance: Performance | undefined; function tryGetPerformance() { if (isNodeLikeSystem()) { try { + // By default, only write native events when generating a cpu profile or using the v8 profiler. const { performance } = require("perf_hooks") as typeof import("perf_hooks"); - return { performance, isGlobal: false }; + return { performance, shouldWriteNativeEvents: false }; } catch { // ignore errors @@ -41,7 +42,10 @@ function tryGetPerformance() { } if (typeof performance === "object") { - return { performance, isGlobal: true }; + // For now we always write native performance events when running in the browser. We may + // make this conditional in the future if we find that native web performance hooks + // in the browser also slow down compilation. + return { performance, shouldWriteNativeEvents: true }; } return undefined; @@ -50,10 +54,10 @@ function tryGetPerformance() { function tryGetPerformanceHooks(): PerformanceHooks | undefined { const p = tryGetPerformance(); if (!p) return undefined; - const { performance, isGlobal } = p; + const { performance, shouldWriteNativeEvents } = p; const hooks: PerformanceHooks = { - isGlobal, + shouldWriteNativeEvents, performance: undefined, performanceTime: undefined, }; @@ -89,5 +93,3 @@ export function tryGetNativePerformanceHooks() { * @internal */ export const timestamp = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now; - -console.log(timestamp === Date.now); From 712e89ecbe7faab569510f2bbd4275050e205aa3 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:11:23 -0700 Subject: [PATCH 7/8] make formatting closer to original code --- src/compiler/performanceCore.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index 7079f581361bf..a6552ecc552e1 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -34,7 +34,10 @@ function tryGetPerformance() { try { // By default, only write native events when generating a cpu profile or using the v8 profiler. const { performance } = require("perf_hooks") as typeof import("perf_hooks"); - return { performance, shouldWriteNativeEvents: false }; + return { + shouldWriteNativeEvents: false, + performance, + }; } catch { // ignore errors @@ -45,7 +48,10 @@ function tryGetPerformance() { // For now we always write native performance events when running in the browser. We may // make this conditional in the future if we find that native web performance hooks // in the browser also slow down compilation. - return { performance, shouldWriteNativeEvents: true }; + return { + shouldWriteNativeEvents: true, + performance, + }; } return undefined; From 9ba1548eb009247ada9d80475608487ed7f984ee Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:14:42 -0700 Subject: [PATCH 8/8] Full change --- src/compiler/performanceCore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index a6552ecc552e1..e788836d11866 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -60,7 +60,7 @@ function tryGetPerformance() { function tryGetPerformanceHooks(): PerformanceHooks | undefined { const p = tryGetPerformance(); if (!p) return undefined; - const { performance, shouldWriteNativeEvents } = p; + const { shouldWriteNativeEvents, performance } = p; const hooks: PerformanceHooks = { shouldWriteNativeEvents,