diff --git a/packages/common/http/src/transfer_cache.ts b/packages/common/http/src/transfer_cache.ts index 9b1fd2d41d4d5..7f7eb772e1ead 100644 --- a/packages/common/http/src/transfer_cache.ts +++ b/packages/common/http/src/transfer_cache.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {APP_BOOTSTRAP_LISTENER, ApplicationRef, inject, InjectionToken, makeStateKey, Provider, StateKey, TransferState, ɵformatRuntimeError as formatRuntimeError, ɵtruncateMiddle as truncateMiddle, ɵwhenStable as whenStable} from '@angular/core'; +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'; import {Observable, of} from 'rxjs'; import {tap} from 'rxjs/operators'; @@ -227,7 +227,7 @@ export function withHttpTransferCache(cacheOptions: HttpTransferCacheOptions): P { provide: CACHE_OPTIONS, useFactory: (): CacheOptions => { - performance.mark('mark_use_counter', {detail: {feature: 'NgHttpTransferCache'}}); + performanceMark('mark_use_counter', {detail: {feature: 'NgHttpTransferCache'}}); return {isCacheActive: true, ...cacheOptions}; } }, diff --git a/packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts b/packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts index 6ca58c38605c5..3ac4f538b64b5 100644 --- a/packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts +++ b/packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -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, ɵRuntimeError as RuntimeError, ɵSafeValue as SafeValue, ɵunwrapSafeValue as unwrapSafeValue} from '@angular/core'; +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'; import {RuntimeErrorCode} from '../../errors'; import {isPlatformServer} from '../../platform_id'; @@ -302,7 +302,7 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy { /** @nodoc */ ngOnInit() { - performance.mark('mark_use_counter', {'detail': {'feature': 'NgOptimizedImage'}}); + performanceMark('mark_use_counter', {'detail': {'feature': 'NgOptimizedImage'}}); if (ngDevMode) { const ngZone = this.injector.get(NgZone); diff --git a/packages/core/src/core_private_export.ts b/packages/core/src/core_private_export.ts index 75df01dda7ee3..e02fe02af9e08 100644 --- a/packages/core/src/core_private_export.ts +++ b/packages/core/src/core_private_export.ts @@ -41,5 +41,6 @@ export {booleanAttribute, numberAttribute} from './util/coercion'; export {devModeEqual as ɵdevModeEqual} from './util/comparison'; export {global as ɵglobal} from './util/global'; export {isPromise as ɵisPromise, isSubscribable as ɵisSubscribable} from './util/lang'; +export {performanceMark as ɵperformanceMark} from './util/performance'; export {stringify as ɵstringify, truncateMiddle as ɵtruncateMiddle} from './util/stringify'; export {NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR} from './view/provider_flags'; diff --git a/packages/core/src/defer/instructions.ts b/packages/core/src/defer/instructions.ts index ad489700f3094..64f04c20ef332 100644 --- a/packages/core/src/defer/instructions.ts +++ b/packages/core/src/defer/instructions.ts @@ -29,6 +29,7 @@ import {isPlatformBrowser} from '../render3/util/misc_utils'; import {getConstant, getTNode, removeLViewOnDestroy, storeLViewOnDestroy} from '../render3/util/view_utils'; import {addLViewToLContainer, createAndRenderEmbeddedLView, removeLViewFromLContainer, shouldAddViewToDom} from '../render3/view_manipulation'; import {assertDefined, throwError} from '../util/assert'; +import {performanceMark} from '../util/performance'; import {invokeAllTriggerCleanupFns, invokeTriggerCleanupFns, storeTriggerCleanupFn} from './cleanup'; import {onHover, onInteraction, onViewport, registerDomTrigger} from './dom_triggers'; @@ -129,7 +130,7 @@ export function ɵɵdefer( ɵɵtemplate(index, null, 0, 0); if (tView.firstCreatePass) { - performance.mark('mark_use_counter', {detail: {feature: 'NgDefer'}}); + performanceMark('mark_use_counter', {detail: {feature: 'NgDefer'}}); const tDetails: TDeferBlockDetails = { primaryTmplIndex, diff --git a/packages/core/src/hydration/api.ts b/packages/core/src/hydration/api.ts index 092cc38d5f9a5..cb38f59516ff7 100644 --- a/packages/core/src/hydration/api.ts +++ b/packages/core/src/hydration/api.ts @@ -20,6 +20,7 @@ import {enableLocateOrCreateTextNodeImpl} from '../render3/instructions/text'; import {getDocument} from '../render3/interfaces/document'; import {isPlatformBrowser} from '../render3/util/misc_utils'; import {TransferState} from '../transfer_state'; +import {performanceMark} from '../util/performance'; import {NgZone} from '../zone'; import {cleanupDehydratedViews} from './cleanup'; @@ -136,7 +137,7 @@ export function withDomHydration(): EnvironmentProviders { } } if (isEnabled) { - performance.mark('mark_use_counter', {detail: {feature: 'NgHydration'}}); + performanceMark('mark_use_counter', {detail: {feature: 'NgHydration'}}); } return isEnabled; }, diff --git a/packages/core/src/render3/after_render_hooks.ts b/packages/core/src/render3/after_render_hooks.ts index f55e8b5557d3d..ec9ceb36a907b 100644 --- a/packages/core/src/render3/after_render_hooks.ts +++ b/packages/core/src/render3/after_render_hooks.ts @@ -13,6 +13,7 @@ import {ErrorHandler} from '../error_handler'; import {RuntimeError, RuntimeErrorCode} from '../errors'; import {DestroyRef} from '../linker/destroy_ref'; import {assertGreaterThan} from '../util/assert'; +import {performanceMark} from '../util/performance'; import {NgZone} from '../zone'; import {isPlatformBrowser} from './util/misc_utils'; @@ -224,7 +225,7 @@ export function afterRender(callback: VoidFunction, options?: AfterRenderOptions return NOOP_AFTER_RENDER_REF; } - performance.mark('mark_use_counter', {detail: {feature: 'NgAfterRender'}}); + performanceMark('mark_use_counter', {detail: {feature: 'NgAfterRender'}}); const afterRenderEventManager = injector.get(AfterRenderEventManager); // Lazily initialize the handler implementation, if necessary. This is so that it can be @@ -300,7 +301,7 @@ export function afterNextRender( return NOOP_AFTER_RENDER_REF; } - performance.mark('mark_use_counter', {detail: {feature: 'NgAfterNextRender'}}); + performanceMark('mark_use_counter', {detail: {feature: 'NgAfterNextRender'}}); const afterRenderEventManager = injector.get(AfterRenderEventManager); // Lazily initialize the handler implementation, if necessary. This is so that it can be diff --git a/packages/core/src/render3/features/standalone_feature.ts b/packages/core/src/render3/features/standalone_feature.ts index aa1f01af32eac..0ad4dfc035d17 100644 --- a/packages/core/src/render3/features/standalone_feature.ts +++ b/packages/core/src/render3/features/standalone_feature.ts @@ -10,6 +10,7 @@ import {ɵɵdefineInjectable as defineInjectable} from '../../di/interface/defs' import {internalImportProvidersFrom} from '../../di/provider_collection'; import {EnvironmentInjector} from '../../di/r3_injector'; import {OnDestroy} from '../../interface/lifecycle_hooks'; +import {performanceMark} from '../../util/performance'; import {ComponentDef} from '../interfaces/definition'; import {createEnvironmentInjector} from '../ng_module_ref'; @@ -75,7 +76,7 @@ const PERF_MARK_STANDALONE = { * @codeGenApi */ export function ɵɵStandaloneFeature(definition: ComponentDef) { - performance.mark('mark_use_counter', PERF_MARK_STANDALONE); + performanceMark('mark_use_counter', PERF_MARK_STANDALONE); definition.getStandaloneInjector = (parentInjector: EnvironmentInjector) => { return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition); }; diff --git a/packages/core/src/render3/instructions/control_flow.ts b/packages/core/src/render3/instructions/control_flow.ts index bfb02fcf5d36d..4240990e290c5 100644 --- a/packages/core/src/render3/instructions/control_flow.ts +++ b/packages/core/src/render3/instructions/control_flow.ts @@ -12,6 +12,7 @@ import {TrackByFunction} from '../../change_detection'; import {DehydratedContainerView} from '../../hydration/interfaces'; import {findMatchingDehydratedView} from '../../hydration/views'; import {assertDefined} from '../../util/assert'; +import {performanceMark} from '../../util/performance'; import {assertLContainer, assertLView, assertTNode} from '../assert'; import {bindingUpdated} from '../bindings'; import {CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container'; @@ -42,7 +43,7 @@ const PERF_MARK_CONTROL_FLOW = { * @codeGenApi */ export function ɵɵconditional(containerIndex: number, matchingTemplateIndex: number, value?: T) { - performance.mark('mark_use_counter', PERF_MARK_CONTROL_FLOW); + performanceMark('mark_use_counter', PERF_MARK_CONTROL_FLOW); const hostLView = getLView(); const bindingIndex = nextBindingIndex(); @@ -148,7 +149,7 @@ export function ɵɵrepeaterCreate( tagName: string|null, attrsIndex: number|null, trackByFn: TrackByFunction, trackByUsesComponentInstance?: boolean, emptyTemplateFn?: ComponentTemplate, emptyDecls?: number, emptyVars?: number): void { - performance.mark('mark_use_counter', PERF_MARK_CONTROL_FLOW); + performanceMark('mark_use_counter', PERF_MARK_CONTROL_FLOW); const hasEmptyBlock = emptyTemplateFn !== undefined; const hostLView = getLView(); const boundTrackBy = trackByUsesComponentInstance ? diff --git a/packages/core/src/util/performance.ts b/packages/core/src/util/performance.ts new file mode 100644 index 0000000000000..78bb7d65c4393 --- /dev/null +++ b/packages/core/src/util/performance.ts @@ -0,0 +1,22 @@ +/** + * @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.io/license + */ + +// tslint:disable:no-performance +/** + * A guarded `performance.mark`. + * + * This method exists because while all supported browser and node.js version supported by Angular + * support performance.mark API. This is not the case for other environments such as JSDOM and + * Cloudflare workers. + */ +export function performanceMark( + markName: string, + markOptions?: PerformanceMarkOptions|undefined, + ): PerformanceMark|undefined { + return performance?.mark?.(markName, markOptions); +} diff --git a/packages/core/test/bundling/defer/bundle.golden_symbols.json b/packages/core/test/bundling/defer/bundle.golden_symbols.json index 74f54e3673d61..79946d88087ee 100644 --- a/packages/core/test/bundling/defer/bundle.golden_symbols.json +++ b/packages/core/test/bundling/defer/bundle.golden_symbols.json @@ -1685,6 +1685,9 @@ { "name": "init_partial" }, + { + "name": "init_performance" + }, { "name": "init_pipe" }, @@ -2204,6 +2207,9 @@ { "name": "onLeave" }, + { + "name": "performanceMark" + }, { "name": "populateDehydratedViewsInLContainer" }, diff --git a/packages/core/test/bundling/hydration/bundle.golden_symbols.json b/packages/core/test/bundling/hydration/bundle.golden_symbols.json index 31a6088f1d0cf..faf1d854f0c30 100644 --- a/packages/core/test/bundling/hydration/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hydration/bundle.golden_symbols.json @@ -1178,6 +1178,9 @@ { "name": "onLeave" }, + { + "name": "performanceMark" + }, { "name": "populateDehydratedViewsInLContainerImpl" },