Skip to content

Commit b16fc26

Browse files
fix(core): limit rate of markers invocations (#52742)
This PR assures that the performance markers are invoked only once for a given feature. Closes #52524 PR Close #52742
1 parent cfb42ee commit b16fc26

File tree

14 files changed

+43
-47
lines changed

14 files changed

+43
-47
lines changed

packages/common/http/src/transfer_cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {APP_BOOTSTRAP_LISTENER, ApplicationRef, inject, InjectionToken, makeStateKey, Provider, StateKey, TransferState, ɵformatRuntimeError as formatRuntimeError, ɵperformanceMark as performanceMark, ɵtruncateMiddle as truncateMiddle, ɵwhenStable as whenStable} from '@angular/core';
9+
import {APP_BOOTSTRAP_LISTENER, ApplicationRef, inject, InjectionToken, makeStateKey, Provider, StateKey, TransferState, ɵformatRuntimeError as formatRuntimeError, ɵperformanceMarkFeature as performanceMarkFeature, ɵtruncateMiddle as truncateMiddle, ɵwhenStable as whenStable} from '@angular/core';
1010
import {Observable, of} from 'rxjs';
1111
import {tap} from 'rxjs/operators';
1212

@@ -227,7 +227,7 @@ export function withHttpTransferCache(cacheOptions: HttpTransferCacheOptions): P
227227
{
228228
provide: CACHE_OPTIONS,
229229
useFactory: (): CacheOptions => {
230-
performanceMark('mark_use_counter', {detail: {feature: 'NgHttpTransferCache'}});
230+
performanceMarkFeature('NgHttpTransferCache');
231231
return {isCacheActive: true, ...cacheOptions};
232232
}
233233
},

packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {booleanAttribute, Directive, ElementRef, inject, Injector, Input, NgZone, numberAttribute, OnChanges, OnDestroy, OnInit, PLATFORM_ID, Renderer2, SimpleChanges, ɵformatRuntimeError as formatRuntimeError, ɵIMAGE_CONFIG as IMAGE_CONFIG, ɵIMAGE_CONFIG_DEFAULTS as IMAGE_CONFIG_DEFAULTS, ɵImageConfig as ImageConfig, ɵperformanceMark as performanceMark, ɵRuntimeError as RuntimeError, ɵSafeValue as SafeValue, ɵunwrapSafeValue as unwrapSafeValue} from '@angular/core';
9+
import {booleanAttribute, Directive, ElementRef, inject, Injector, Input, NgZone, numberAttribute, OnChanges, OnDestroy, OnInit, PLATFORM_ID, Renderer2, SimpleChanges, ɵformatRuntimeError as formatRuntimeError, ɵIMAGE_CONFIG as IMAGE_CONFIG, ɵIMAGE_CONFIG_DEFAULTS as IMAGE_CONFIG_DEFAULTS, ɵImageConfig as ImageConfig, ɵperformanceMarkFeature as performanceMarkFeature, ɵRuntimeError as RuntimeError, ɵSafeValue as SafeValue, ɵunwrapSafeValue as unwrapSafeValue} from '@angular/core';
1010

1111
import {RuntimeErrorCode} from '../../errors';
1212
import {isPlatformServer} from '../../platform_id';
@@ -302,7 +302,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
302302

303303
/** @nodoc */
304304
ngOnInit() {
305-
performanceMark('mark_use_counter', {'detail': {'feature': 'NgOptimizedImage'}});
305+
performanceMarkFeature('NgOptimizedImage');
306306

307307
if (ngDevMode) {
308308
const ngZone = this.injector.get(NgZone);

packages/core/src/core_private_export.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ export {booleanAttribute, numberAttribute} from './util/coercion';
4141
export {devModeEqual as ɵdevModeEqual} from './util/comparison';
4242
export {global as ɵglobal} from './util/global';
4343
export {isPromise as ɵisPromise, isSubscribable as ɵisSubscribable} from './util/lang';
44-
export {performanceMark as ɵperformanceMark} from './util/performance';
44+
export {performanceMarkFeature as ɵperformanceMarkFeature} from './util/performance';
4545
export {stringify as ɵstringify, truncateMiddle as ɵtruncateMiddle} from './util/stringify';
4646
export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider_flags';

packages/core/src/defer/instructions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {isPlatformBrowser} from '../render3/util/misc_utils';
2929
import {getConstant, getTNode, removeLViewOnDestroy, storeLViewOnDestroy} from '../render3/util/view_utils';
3030
import {addLViewToLContainer, createAndRenderEmbeddedLView, removeLViewFromLContainer, shouldAddViewToDom} from '../render3/view_manipulation';
3131
import {assertDefined, throwError} from '../util/assert';
32-
import {performanceMark} from '../util/performance';
32+
import {performanceMarkFeature} from '../util/performance';
3333

3434
import {invokeAllTriggerCleanupFns, invokeTriggerCleanupFns, storeTriggerCleanupFn} from './cleanup';
3535
import {onHover, onInteraction, onViewport, registerDomTrigger} from './dom_triggers';
@@ -130,7 +130,7 @@ export function ɵɵdefer(
130130
ɵɵtemplate(index, null, 0, 0);
131131

132132
if (tView.firstCreatePass) {
133-
performanceMark('mark_use_counter', {detail: {feature: 'NgDefer'}});
133+
performanceMarkFeature('NgDefer');
134134

135135
const tDetails: TDeferBlockDetails = {
136136
primaryTmplIndex,

packages/core/src/hydration/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {enableLocateOrCreateTextNodeImpl} from '../render3/instructions/text';
2020
import {getDocument} from '../render3/interfaces/document';
2121
import {isPlatformBrowser} from '../render3/util/misc_utils';
2222
import {TransferState} from '../transfer_state';
23-
import {performanceMark} from '../util/performance';
23+
import {performanceMarkFeature} from '../util/performance';
2424
import {NgZone} from '../zone';
2525

2626
import {cleanupDehydratedViews} from './cleanup';
@@ -137,7 +137,7 @@ export function withDomHydration(): EnvironmentProviders {
137137
}
138138
}
139139
if (isEnabled) {
140-
performanceMark('mark_use_counter', {detail: {feature: 'NgHydration'}});
140+
performanceMarkFeature('NgHydration');
141141
}
142142
return isEnabled;
143143
},

packages/core/src/render3/after_render_hooks.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {ErrorHandler} from '../error_handler';
1313
import {RuntimeError, RuntimeErrorCode} from '../errors';
1414
import {DestroyRef} from '../linker/destroy_ref';
1515
import {assertGreaterThan} from '../util/assert';
16-
import {performanceMark} from '../util/performance';
16+
import {performanceMarkFeature} from '../util/performance';
1717
import {NgZone} from '../zone';
1818

1919
import {isPlatformBrowser} from './util/misc_utils';
@@ -225,7 +225,7 @@ export function afterRender(callback: VoidFunction, options?: AfterRenderOptions
225225
return NOOP_AFTER_RENDER_REF;
226226
}
227227

228-
performanceMark('mark_use_counter', {detail: {feature: 'NgAfterRender'}});
228+
performanceMarkFeature('NgAfterRender');
229229

230230
const afterRenderEventManager = injector.get(AfterRenderEventManager);
231231
// Lazily initialize the handler implementation, if necessary. This is so that it can be
@@ -301,7 +301,7 @@ export function afterNextRender(
301301
return NOOP_AFTER_RENDER_REF;
302302
}
303303

304-
performanceMark('mark_use_counter', {detail: {feature: 'NgAfterNextRender'}});
304+
performanceMarkFeature('NgAfterNextRender');
305305

306306
const afterRenderEventManager = injector.get(AfterRenderEventManager);
307307
// Lazily initialize the handler implementation, if necessary. This is so that it can be

packages/core/src/render3/features/standalone_feature.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {ɵɵdefineInjectable as defineInjectable} from '../../di/interface/defs'
1010
import {internalImportProvidersFrom} from '../../di/provider_collection';
1111
import {EnvironmentInjector} from '../../di/r3_injector';
1212
import {OnDestroy} from '../../interface/lifecycle_hooks';
13-
import {performanceMark} from '../../util/performance';
13+
import {performanceMarkFeature} from '../../util/performance';
1414
import {ComponentDef} from '../interfaces/definition';
1515
import {createEnvironmentInjector} from '../ng_module_ref';
1616

@@ -61,9 +61,6 @@ class StandaloneService implements OnDestroy {
6161
});
6262
}
6363

64-
const PERF_MARK_STANDALONE = {
65-
detail: {feature: 'NgStandalone'}
66-
};
6764

6865
/**
6966
* A feature that acts as a setup code for the {@link StandaloneService}.
@@ -76,7 +73,7 @@ const PERF_MARK_STANDALONE = {
7673
* @codeGenApi
7774
*/
7875
export function ɵɵStandaloneFeature(definition: ComponentDef<unknown>) {
79-
performanceMark('mark_use_counter', PERF_MARK_STANDALONE);
76+
performanceMarkFeature('NgStandalone');
8077
definition.getStandaloneInjector = (parentInjector: EnvironmentInjector) => {
8178
return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
8279
};

packages/core/src/render3/instructions/control_flow.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {TrackByFunction} from '../../change_detection';
1212
import {DehydratedContainerView} from '../../hydration/interfaces';
1313
import {findMatchingDehydratedView} from '../../hydration/views';
1414
import {assertDefined} from '../../util/assert';
15-
import {performanceMark} from '../../util/performance';
15+
import {performanceMarkFeature} from '../../util/performance';
1616
import {assertLContainer, assertLView, assertTNode} from '../assert';
1717
import {bindingUpdated} from '../bindings';
1818
import {CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container';
@@ -27,10 +27,6 @@ import {addLViewToLContainer, createAndRenderEmbeddedLView, getLViewFromLContain
2727

2828
import {ɵɵtemplate} from './template';
2929

30-
const PERF_MARK_CONTROL_FLOW = {
31-
detail: {feature: 'NgControlFlow'}
32-
};
33-
3430
/**
3531
* The conditional instruction represents the basic building block on the runtime side to support
3632
* built-in "if" and "switch". On the high level this instruction is responsible for adding and
@@ -43,7 +39,7 @@ const PERF_MARK_CONTROL_FLOW = {
4339
* @codeGenApi
4440
*/
4541
export function ɵɵconditional<T>(containerIndex: number, matchingTemplateIndex: number, value?: T) {
46-
performanceMark('mark_use_counter', PERF_MARK_CONTROL_FLOW);
42+
performanceMarkFeature('NgControlFlow');
4743

4844
const hostLView = getLView();
4945
const bindingIndex = nextBindingIndex();
@@ -149,7 +145,7 @@ export function ɵɵrepeaterCreate(
149145
tagName: string|null, attrsIndex: number|null, trackByFn: TrackByFunction<unknown>,
150146
trackByUsesComponentInstance?: boolean, emptyTemplateFn?: ComponentTemplate<unknown>,
151147
emptyDecls?: number, emptyVars?: number): void {
152-
performanceMark('mark_use_counter', PERF_MARK_CONTROL_FLOW);
148+
performanceMarkFeature('NgControlFlow');
153149
const hasEmptyBlock = emptyTemplateFn !== undefined;
154150
const hostLView = getLView();
155151
const boundTrackBy = trackByUsesComponentInstance ?

packages/core/src/util/performance.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,20 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
const markedFeatures = new Set<string>();
10+
911
// tslint:disable:ban
1012
/**
11-
* A guarded `performance.mark`.
13+
* A guarded `performance.mark` for feature marking.
1214
*
1315
* This method exists because while all supported browser and node.js version supported by Angular
1416
* support performance.mark API. This is not the case for other environments such as JSDOM and
1517
* Cloudflare workers.
1618
*/
17-
export function performanceMark(
18-
markName: string,
19-
markOptions?: PerformanceMarkOptions|undefined,
20-
): PerformanceMark|undefined {
21-
return performance?.mark?.(markName, markOptions);
19+
export function performanceMarkFeature(feature: string): void {
20+
if (markedFeatures.has(feature)) {
21+
return;
22+
}
23+
markedFeatures.add(feature);
24+
performance?.mark?.('mark_use_counter', {detail: {feature}});
2225
}

packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,6 @@
404404
{
405405
"name": "PARAM_REGEX"
406406
},
407-
{
408-
"name": "PERF_MARK_STANDALONE"
409-
},
410407
{
411408
"name": "PLATFORM_DESTROY_LISTENERS"
412409
},
@@ -1208,6 +1205,9 @@
12081205
{
12091206
"name": "markViewForRefresh"
12101207
},
1208+
{
1209+
"name": "markedFeatures"
1210+
},
12111211
{
12121212
"name": "maybeWrapInNotSelector"
12131213
},

0 commit comments

Comments
 (0)