mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Use performance.now when possible, re-disable unconditional perf marking on all Node versions (#57875)
This commit is contained in:
parent
b75261df74
commit
3c637400da
@ -180,7 +180,7 @@ 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`
|
||||
|
||||
@ -7,104 +7,86 @@ import {
|
||||
|
||||
/** @internal */
|
||||
export interface PerformanceHooks {
|
||||
/** Indicates whether we should write native performance events */
|
||||
shouldWriteNativeEvents: boolean;
|
||||
performance: Performance;
|
||||
PerformanceObserver: PerformanceObserverConstructor;
|
||||
performance?: Performance;
|
||||
performanceTime?: PerformanceTime;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface Performance {
|
||||
mark(name: string): void;
|
||||
measure(name: string, startMark?: string, endMark?: string): void;
|
||||
clearMeasures(name?: string): void;
|
||||
clearMarks(name?: string): void;
|
||||
export interface PerformanceTime {
|
||||
now(): number;
|
||||
timeOrigin: number;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface PerformanceEntry {
|
||||
name: string;
|
||||
entryType: string;
|
||||
startTime: number;
|
||||
duration: number;
|
||||
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 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) {
|
||||
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";
|
||||
}
|
||||
|
||||
function tryGetWebPerformanceHooks(): PerformanceHooks | undefined {
|
||||
if (
|
||||
typeof performance === "object" &&
|
||||
typeof PerformanceObserver === "function" &&
|
||||
hasRequiredAPI(performance, PerformanceObserver)
|
||||
) {
|
||||
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,
|
||||
PerformanceObserver,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetNodePerformanceHooks(): PerformanceHooks | undefined {
|
||||
function tryGetPerformance() {
|
||||
if (isNodeLikeSystem()) {
|
||||
try {
|
||||
const { performance, PerformanceObserver } = require("perf_hooks") as typeof import("perf_hooks");
|
||||
if (hasRequiredAPI(performance, PerformanceObserver)) {
|
||||
return {
|
||||
// By default, only write native events when generating a cpu profile or using the v8 profiler.
|
||||
shouldWriteNativeEvents: false,
|
||||
performance,
|
||||
PerformanceObserver,
|
||||
};
|
||||
}
|
||||
// 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 {
|
||||
shouldWriteNativeEvents: false,
|
||||
performance,
|
||||
};
|
||||
}
|
||||
catch {
|
||||
// ignore errors
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof performance === "object") {
|
||||
// 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 {
|
||||
shouldWriteNativeEvents: true,
|
||||
performance,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 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;
|
||||
function tryGetPerformanceHooks(): PerformanceHooks | undefined {
|
||||
const p = tryGetPerformance();
|
||||
if (!p) return undefined;
|
||||
const { shouldWriteNativeEvents, performance } = p;
|
||||
|
||||
const hooks: PerformanceHooks = {
|
||||
shouldWriteNativeEvents,
|
||||
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;
|
||||
}
|
||||
|
||||
const nativePerformanceHooks = tryGetPerformanceHooks();
|
||||
const nativePerformanceTime = nativePerformanceHooks?.performanceTime;
|
||||
|
||||
/** @internal */
|
||||
export function tryGetNativePerformanceHooks() {
|
||||
@ -116,6 +98,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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user