From 640f5bf6d3f4da8c3f4d3d750565acf85ae0fadc Mon Sep 17 00:00:00 2001 From: AleksanderBodurri Date: Sun, 2 Mar 2025 21:30:23 -0500 Subject: [PATCH] feat(core): emit template function for template related profiler hooks Previously, the profiler would only emit the specific template event and context when a template is created/updated, but not the template function related to the event. This commit emits this function by using the third argument of the profiler function, which previously was only used for lifecycle hooks and output listeners. This commit also renames this arg to eventFn to express that it varies depending on the event type emitting from the profiler. Note: this change is fully backwards compatible, since previously these template events did not use the third arg of the profiler function. --- .../src/lib/hooks/profiler/native.ts | 70 +++++++++---------- .../core/src/render3/instructions/shared.ts | 4 +- packages/core/src/render3/profiler.ts | 9 +-- packages/core/src/render3/profiler_types.ts | 2 +- .../core/test/acceptance/profiler_spec.ts | 6 +- 5 files changed, 41 insertions(+), 50 deletions(-) diff --git a/devtools/projects/ng-devtools-backend/src/lib/hooks/profiler/native.ts b/devtools/projects/ng-devtools-backend/src/lib/hooks/profiler/native.ts index c9e05625fedb..597044cfcc67 100644 --- a/devtools/projects/ng-devtools-backend/src/lib/hooks/profiler/native.ts +++ b/devtools/projects/ng-devtools-backend/src/lib/hooks/profiler/native.ts @@ -15,11 +15,7 @@ import {IdentityTracker, NodeArray} from '../identity-tracker'; import {getLifeCycleName, Hooks, Profiler} from './shared'; -type ProfilerCallback = ( - event: ɵProfilerEvent, - instanceOrLView: {} | null, - hookOrListener: any, -) => void; +type ProfilerCallback = (event: ɵProfilerEvent, instanceOrLView: {} | null, eventFn: any) => void; /** Implementation of Profiler that utilizes framework APIs fire profiler hooks. */ export class NgProfiler extends Profiler { @@ -29,22 +25,20 @@ export class NgProfiler extends Profiler { constructor(config: Partial = {}) { super(config); - this._setProfilerCallback( - (event: ɵProfilerEvent, instanceOrLView: {} | null, hookOrListener: any) => { - if (this[event] === undefined) { - return; - } - - this[event](instanceOrLView, hookOrListener); - }, - ); + this._setProfilerCallback((event: ɵProfilerEvent, instanceOrLView: {} | null, eventFn: any) => { + if (this[event] === undefined) { + return; + } + + this[event](instanceOrLView, eventFn); + }); this._initialize(); } private _initialize(): void { ngDebugClient().ɵsetProfiler( - (event: ɵProfilerEvent, instanceOrLView: {} | null = null, hookOrListener: any) => - this._callbacks.forEach((cb) => cb(event, instanceOrLView, hookOrListener)), + (event: ɵProfilerEvent, instanceOrLView: {} | null = null, eventFn: any) => + this._callbacks.forEach((cb) => cb(event, instanceOrLView, eventFn)), ); } @@ -74,107 +68,107 @@ export class NgProfiler extends Profiler { }); } - [ɵProfilerEvent.BootstrapApplicationStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.BootstrapApplicationStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.BootstrapApplicationEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.BootstrapApplicationEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.BootstrapComponentStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.BootstrapComponentStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.BootstrapComponentEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.BootstrapComponentEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ChangeDetectionStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ChangeDetectionStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ChangeDetectionEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ChangeDetectionEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ChangeDetectionSyncStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ChangeDetectionSyncStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ChangeDetectionSyncEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ChangeDetectionSyncEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.AfterRenderHooksStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.AfterRenderHooksStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.AfterRenderHooksEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.AfterRenderHooksEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ComponentStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ComponentStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.ComponentEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.ComponentEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.DeferBlockStateStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.DeferBlockStateStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.DeferBlockStateEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.DeferBlockStateEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.DynamicComponentStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.DynamicComponentStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.DynamicComponentEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.DynamicComponentEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.HostBindingsUpdateStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.HostBindingsUpdateStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.HostBindingsUpdateEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.HostBindingsUpdateEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.TemplateCreateStart](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.TemplateCreateStart](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.TemplateCreateEnd](_directive: any, _hookOrListener: any): void { + [ɵProfilerEvent.TemplateCreateEnd](_directive: any, _eventFn: any): void { // todo: implement return; } - [ɵProfilerEvent.TemplateUpdateStart](context: any, _hookOrListener: any): void { + [ɵProfilerEvent.TemplateUpdateStart](context: any, _eventFn: any): void { if (!this._inChangeDetection) { this._inChangeDetection = true; runOutsideAngular(() => { @@ -208,7 +202,7 @@ export class NgProfiler extends Profiler { ); } - [ɵProfilerEvent.TemplateUpdateEnd](context: any, _hookOrListener: any): void { + [ɵProfilerEvent.TemplateUpdateEnd](context: any, _eventFn: any): void { const position = this._tracker.getDirectivePosition(context); const id = this._tracker.getDirectiveId(context); diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index dc1c6e4fea70..0200b8af1bb9 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -96,7 +96,7 @@ export function executeTemplate( const preHookType = isUpdatePhase ? ProfilerEvent.TemplateUpdateStart : ProfilerEvent.TemplateCreateStart; - profiler(preHookType, context as unknown as {}); + profiler(preHookType, context as unknown as {}, templateFn); templateFn(rf, context); } finally { setSelectedIndex(prevSelectedIndex); @@ -104,7 +104,7 @@ export function executeTemplate( const postHookType = isUpdatePhase ? ProfilerEvent.TemplateUpdateEnd : ProfilerEvent.TemplateCreateEnd; - profiler(postHookType, context as unknown as {}); + profiler(postHookType, context as unknown as {}, templateFn); } } diff --git a/packages/core/src/render3/profiler.ts b/packages/core/src/render3/profiler.ts index d52d232e00a9..1d7d1a0e60ef 100644 --- a/packages/core/src/render3/profiler.ts +++ b/packages/core/src/render3/profiler.ts @@ -29,12 +29,13 @@ export const setProfiler = (profiler: Profiler | null) => { * * @param event ProfilerEvent corresponding to the execution context * @param instance component instance - * @param hookOrListener lifecycle hook function or output listener. The value depends on the - * execution context + * @param eventFn function associated with event. + * For example a template function, lifecycle hook, or output listener. + * The value depends on the execution context * @returns */ -export const profiler: Profiler = function (event, instance = null, hookOrListener) { +export const profiler: Profiler = function (event, instance = null, eventFn) { if (profilerCallback != null /* both `null` and `undefined` */) { - profilerCallback(event, instance, hookOrListener); + profilerCallback(event, instance, eventFn); } }; diff --git a/packages/core/src/render3/profiler_types.ts b/packages/core/src/render3/profiler_types.ts index f8a42a2d8447..9f88e6d4dc0d 100644 --- a/packages/core/src/render3/profiler_types.ts +++ b/packages/core/src/render3/profiler_types.ts @@ -160,5 +160,5 @@ export const enum ProfilerEvent { * Profiler function which the runtime will invoke before and after user code. */ export interface Profiler { - (event: ProfilerEvent, instance?: {} | null, hookOrListener?: (e?: any) => any): void; + (event: ProfilerEvent, instance?: {} | null, eventFn?: Function): void; } diff --git a/packages/core/test/acceptance/profiler_spec.ts b/packages/core/test/acceptance/profiler_spec.ts index 52bdc41fbbf1..cadea071bfc3 100644 --- a/packages/core/test/acceptance/profiler_spec.ts +++ b/packages/core/test/acceptance/profiler_spec.ts @@ -443,11 +443,7 @@ describe('profiler', () => { return true; } - profile = ( - event: ProfilerEvent, - instance?: {} | null, - hookOrListener?: (e?: any) => any, - ): void => { + profile = (event: ProfilerEvent, instance?: {} | null, eventFn?: Function): void => { this.events.push(event); }; }