fix(devtools): avoid initializing profiler in production mode

Defer the timing hook subscription until the timing API is explicitly enabled. Keep production module loading and development initialization covered by isolated browser test targets.
This commit is contained in:
splincode
2026-07-27 15:25:52 +03:00
committed by Douglas Parker
parent c6e4d5ad6f
commit 1a2bcb2295
3 changed files with 64 additions and 6 deletions
@@ -1,4 +1,4 @@
load("//devtools/tools:defaults.bzl", "ts_project")
load("//devtools/tools:defaults.bzl", "ts_project", "ts_test_library", "zoneless_web_test_suite")
package(default_visibility = ["//devtools:__subpackages__"])
@@ -21,3 +21,16 @@ ts_project(
"//devtools/projects/protocol",
],
)
ts_test_library(
name = "performance_track_test_lib",
srcs = ["performance-track.spec.ts"],
deps = [
":profiling",
],
)
zoneless_web_test_suite(
name = "performance_track_test",
deps = [":performance_track_test_lib"],
)
@@ -0,0 +1,31 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
describe('performance track', () => {
const globalWithAngularDebugApi = window as unknown as {ng?: unknown};
let angularDebugApi: unknown;
beforeEach(() => {
angularDebugApi = globalWithAngularDebugApi.ng;
globalWithAngularDebugApi.ng = {};
});
afterEach(() => {
if (angularDebugApi === undefined) {
delete globalWithAngularDebugApi.ng;
} else {
globalWithAngularDebugApi.ng = angularDebugApi;
}
});
it('does not throw an error when initialized in development mode', async () => {
const performanceTrack = await import('./performance-track');
expect(() => performanceTrack.enablePerformanceTrack()).not.toThrow();
});
});
@@ -16,9 +16,6 @@ type Method = keyof LifecycleProfile | 'changeDetection' | string;
// Performance track global flag.
let chromeDevToolsPerformanceTrackEnabled = false;
/** Enable Angular's performance track in the Chrome DevTools profiler. */
export const enablePerformanceTrack = () => (chromeDevToolsPerformanceTrackEnabled = true);
/** Disable Angular's performance track in the Chrome DevTools profiler. */
export const disablePerformanceTrack = () => (chromeDevToolsPerformanceTrackEnabled = false);
@@ -64,7 +61,7 @@ const endMark = (nodeName: string, method: Method) => {
}
};
getProfiler().subscribe({
const timingHooks = {
onChangeDetectionStart(component: ComponentInstance): void {
if (!performanceTrackEnabled()) {
return;
@@ -101,4 +98,21 @@ getProfiler().subscribe({
}
endMark(getDirectiveName(component), output);
},
});
};
let performanceTrackInitialized = false;
function initializePerformanceTrack(): void {
if (performanceTrackInitialized) {
return;
}
getProfiler().subscribe(timingHooks);
performanceTrackInitialized = true;
}
/** Enable Angular's performance track in the Chrome DevTools profiler. */
export function enablePerformanceTrack(): void {
initializePerformanceTrack();
chromeDevToolsPerformanceTrackEnabled = true;
}