refactor(ivy): remove ngPrivateData megamorphic prop access (#30548)
PR Close #30548
This commit is contained in:
@ -174,11 +174,8 @@ export function createRootComponentView(
|
||||
const tView = rootView[TVIEW];
|
||||
const tNode: TElementNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null);
|
||||
const componentView = createLView(
|
||||
rootView, getOrCreateTView(
|
||||
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs,
|
||||
def.viewQuery, def.schemas),
|
||||
null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, rootView[HEADER_OFFSET], tNode,
|
||||
rendererFactory, renderer, sanitizer);
|
||||
rootView, getOrCreateTView(def), null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways,
|
||||
rootView[HEADER_OFFSET], tNode, rendererFactory, renderer, sanitizer);
|
||||
|
||||
if (tView.firstTemplatePass) {
|
||||
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), rootView, def.type);
|
||||
|
@ -285,6 +285,7 @@ export function ΔdefineComponent<T>(componentDefinition: {
|
||||
_: null as never,
|
||||
setInput: null,
|
||||
schemas: componentDefinition.schemas || null,
|
||||
tView: null,
|
||||
};
|
||||
def._ = noSideEffects(() => {
|
||||
const directiveTypes = componentDefinition.directives !;
|
||||
|
@ -548,29 +548,13 @@ function saveResolvedLocalsInData(
|
||||
* Gets TView from a template function or creates a new TView
|
||||
* if it doesn't already exist.
|
||||
*
|
||||
* @param templateFn The template from which to get static data
|
||||
* @param consts The number of nodes, local refs, and pipes in this view
|
||||
* @param vars The number of bindings and pure function bindings in this view
|
||||
* @param directives Directive defs that should be saved on TView
|
||||
* @param pipes Pipe defs that should be saved on TView
|
||||
* @param viewQuery View query that should be saved on TView
|
||||
* @param schemas Schemas that should be saved on TView
|
||||
* @param def ComponentDef
|
||||
* @returns TView
|
||||
*/
|
||||
export function getOrCreateTView(
|
||||
templateFn: ComponentTemplate<any>, consts: number, vars: number,
|
||||
directives: DirectiveDefListOrFactory | null, pipes: PipeDefListOrFactory | null,
|
||||
viewQuery: ViewQueriesFunction<any>| null, schemas: SchemaMetadata[] | null): TView {
|
||||
// TODO(misko): reading `ngPrivateData` here is problematic for two reasons
|
||||
// 1. It is a megamorphic call on each invocation.
|
||||
// 2. For nested embedded views (ngFor inside ngFor) the template instance is per
|
||||
// outer template invocation, which means that no such property will exist
|
||||
// Correct solution is to only put `ngPrivateData` on the Component template
|
||||
// and not on embedded templates.
|
||||
|
||||
return templateFn.ngPrivateData ||
|
||||
(templateFn.ngPrivateData = createTView(
|
||||
-1, templateFn, consts, vars, directives, pipes, viewQuery, schemas) as never);
|
||||
export function getOrCreateTView(def: ComponentDef<any>): TView {
|
||||
return def.tView || (def.tView = createTView(
|
||||
-1, def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs,
|
||||
def.viewQuery, def.schemas));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1262,9 +1246,7 @@ function addComponentLogic<T>(
|
||||
lView: LView, previousOrParentTNode: TNode, def: ComponentDef<T>): void {
|
||||
const native = getNativeByTNode(previousOrParentTNode, lView);
|
||||
|
||||
const tView = getOrCreateTView(
|
||||
def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery,
|
||||
def.schemas);
|
||||
const tView = getOrCreateTView(def);
|
||||
|
||||
// Only component views should be added to the view tree directly. Embedded views are
|
||||
// accessed through their containers because they may be removed / re-added later.
|
||||
|
@ -10,6 +10,7 @@ import {SchemaMetadata, ViewEncapsulation} from '../../core';
|
||||
import {ProcessProvidersFunction} from '../../di/interface/provider';
|
||||
import {Type} from '../../interface/type';
|
||||
import {CssSelectorList} from './projection';
|
||||
import {TView} from './view';
|
||||
|
||||
|
||||
/**
|
||||
@ -19,7 +20,7 @@ export type ComponentTemplate<T> = {
|
||||
// Note: the ctx parameter is typed as T|U, as using only U would prevent a template with
|
||||
// e.g. ctx: {} from being assigned to ComponentTemplate<any> as TypeScript won't infer U = any
|
||||
// in that scenario. By including T this incompatibility is resolved.
|
||||
<U extends T>(rf: RenderFlags, ctx: T | U): void; ngPrivateData?: never;
|
||||
<U extends T>(rf: RenderFlags, ctx: T | U): void;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -302,6 +303,12 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
*/
|
||||
schemas: SchemaMetadata[]|null;
|
||||
|
||||
/**
|
||||
* Ivy runtime uses this place to store the computed tView for the component. This gets filled on
|
||||
* the first run of component.
|
||||
*/
|
||||
tView: TView|null;
|
||||
|
||||
/**
|
||||
* Used to store the result of `noSideEffects` function so that it is not removed by closure
|
||||
* compiler. The property should never be read.
|
||||
|
@ -327,7 +327,7 @@ export interface ExpandoInstructions extends Array<number|HostBindingsFunction<a
|
||||
* The static data for an LView (shared between all templates of a
|
||||
* given type).
|
||||
*
|
||||
* Stored on the template function as ngPrivateData.
|
||||
* Stored on the `ComponentDef.tView`.
|
||||
*/
|
||||
export interface TView {
|
||||
/**
|
||||
|
@ -361,7 +361,7 @@ export function patchComponentDefWithScope<C>(
|
||||
// may face a problem where previously compiled defs available to a given Component/Directive
|
||||
// are cached in TView and may become stale (in case any of these defs gets recompiled). In
|
||||
// order to avoid this problem, we force fresh TView to be created.
|
||||
componentDef.template.ngPrivateData = undefined;
|
||||
componentDef.tView = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user