perf(ivy): don't store public input names in two places (#33798)

Before this change a public name of a directive's input
was stored in 2 places:
- as a key of an object on TNode.index;
- as a value of PropertyAliasValue at the index 1

This PR changes the data structure so the public name is stored
only once as a key on TNode.index. This saves one array entry
for each and every directive input.

PR Close #33798
This commit is contained in:
Pawel Kozlowski 2019-11-13 17:06:54 +01:00 committed by Alex Rickabaugh
parent 5aec1798eb
commit da0c372fdf
6 changed files with 20 additions and 23 deletions

View File

@ -1021,7 +1021,7 @@ function i18nAttributesFirstPass(lView: LView, tView: TView, index: number, valu
// Check if that attribute is a directive input // Check if that attribute is a directive input
const dataValue = tNode.inputs && tNode.inputs[attrName]; const dataValue = tNode.inputs && tNode.inputs[attrName];
if (dataValue) { if (dataValue) {
setInputsForProperty(lView, dataValue, value); setInputsForProperty(lView, dataValue, attrName, value);
if (ngDevMode) { if (ngDevMode) {
const element = getNativeByIndex(previousElementIndex, lView) as RElement | RComment; const element = getNativeByIndex(previousElementIndex, lView) as RElement | RComment;
setNgReflectProperties(lView, element, tNode.type, dataValue, value); setNgReflectProperties(lView, element, tNode.type, dataValue, value);

View File

@ -134,11 +134,11 @@ export function ɵɵelementEnd(): void {
if (hasClassInput(tNode)) { if (hasClassInput(tNode)) {
const inputName: string = selectClassBasedInputName(tNode.inputs !); const inputName: string = selectClassBasedInputName(tNode.inputs !);
setDirectiveStylingInput(tNode.classes, lView, tNode.inputs ![inputName]); setDirectiveStylingInput(tNode.classes, lView, tNode.inputs ![inputName], inputName);
} }
if (hasStyleInput(tNode)) { if (hasStyleInput(tNode)) {
setDirectiveStylingInput(tNode.styles, lView, tNode.inputs !['style']); setDirectiveStylingInput(tNode.styles, lView, tNode.inputs !['style'], 'style');
} }
} }
@ -231,7 +231,7 @@ export function ɵɵelementHostAttrs(attrs: TAttributes) {
function setDirectiveStylingInput( function setDirectiveStylingInput(
context: TStylingContext | StylingMapArray | null, lView: LView, context: TStylingContext | StylingMapArray | null, lView: LView,
stylingInputs: (string | number)[]) { stylingInputs: (string | number)[], propName: string) {
// older versions of Angular treat the input as `null` in the // older versions of Angular treat the input as `null` in the
// event that the value does not exist at all. For this reason // event that the value does not exist at all. For this reason
// we can't have a styling value be an empty string. // we can't have a styling value be an empty string.
@ -240,7 +240,7 @@ function setDirectiveStylingInput(
// Ivy does an extra `[class]` write with a falsy value since the value // Ivy does an extra `[class]` write with a falsy value since the value
// is applied during creation mode. This is a deviation from VE and should // is applied during creation mode. This is a deviation from VE and should
// be (Jira Issue = FW-1467). // be (Jira Issue = FW-1467).
setInputsForProperty(lView, stylingInputs, value); setInputsForProperty(lView, stylingInputs, propName, value);
} }
function validateElement( function validateElement(

View File

@ -196,10 +196,10 @@ function listenerInternal(
const propsLength = props.length; const propsLength = props.length;
if (propsLength) { if (propsLength) {
const lCleanup = getCleanup(lView); const lCleanup = getCleanup(lView);
for (let i = 0; i < propsLength; i += 3) { for (let i = 0; i < propsLength; i += 2) {
const index = props[i] as number; const index = props[i] as number;
ngDevMode && assertDataInRange(lView, index); ngDevMode && assertDataInRange(lView, index);
const minifiedName = props[i + 2]; const minifiedName = props[i + 1];
const directiveInstance = lView[index]; const directiveInstance = lView[index];
const output = directiveInstance[minifiedName]; const output = directiveInstance[minifiedName];

View File

@ -848,9 +848,9 @@ function generatePropertyAliases(
const internalName = inputAliasMap[publicName]; const internalName = inputAliasMap[publicName];
if (propStore.hasOwnProperty(publicName)) { if (propStore.hasOwnProperty(publicName)) {
propStore[publicName].push(directiveDefIdx, publicName, internalName); propStore[publicName].push(directiveDefIdx, internalName);
} else { } else {
(propStore[publicName] = [directiveDefIdx, publicName, internalName]); (propStore[publicName] = [directiveDefIdx, internalName]);
} }
} }
} }
@ -925,7 +925,7 @@ export function elementPropertyInternal<T>(
let inputData = tNode.inputs; let inputData = tNode.inputs;
let dataValue: PropertyAliasValue|undefined; let dataValue: PropertyAliasValue|undefined;
if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) { if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
setInputsForProperty(lView, dataValue, value); setInputsForProperty(lView, dataValue, propName, value);
if (isComponentHost(tNode)) markDirtyIfOnPush(lView, index + HEADER_OFFSET); if (isComponentHost(tNode)) markDirtyIfOnPush(lView, index + HEADER_OFFSET);
if (ngDevMode) { if (ngDevMode) {
setNgReflectProperties(lView, element, tNode.type, dataValue, value); setNgReflectProperties(lView, element, tNode.type, dataValue, value);
@ -1002,14 +1002,13 @@ export function setNgReflectProperties(
/** /**
* dataValue is an array containing runtime input or output names for the directives: * dataValue is an array containing runtime input or output names for the directives:
* i+0: directive instance index * i+0: directive instance index
* i+1: publicName * i+1: privateName
* i+2: privateName
* *
* e.g. [0, 'change', 'change-minified'] * e.g. [0, 'change', 'change-minified']
* we want to set the reflected property with the privateName: dataValue[i+2] * we want to set the reflected property with the privateName: dataValue[i+1]
*/ */
for (let i = 0; i < dataValue.length; i += 3) { for (let i = 0; i < dataValue.length; i += 2) {
setNgReflectProperty(lView, element, type, dataValue[i + 2] as string, value); setNgReflectProperty(lView, element, type, dataValue[i + 1] as string, value);
} }
} }
} }
@ -1864,17 +1863,16 @@ export function handleError(lView: LView, error: any): void {
* possibly minified, property names to write to. * possibly minified, property names to write to.
* @param value Value to set. * @param value Value to set.
*/ */
export function setInputsForProperty(lView: LView, inputs: PropertyAliasValue, value: any): void { export function setInputsForProperty(
lView: LView, inputs: PropertyAliasValue, publicName: string, value: any): void {
const tView = lView[TVIEW]; const tView = lView[TVIEW];
for (let i = 0; i < inputs.length;) { for (let i = 0; i < inputs.length;) {
const index = inputs[i++] as number; const index = inputs[i++] as number;
const publicName = inputs[i++] as string;
const privateName = inputs[i++] as string; const privateName = inputs[i++] as string;
const instance = lView[index]; const instance = lView[index];
ngDevMode && assertDataInRange(lView, index); ngDevMode && assertDataInRange(lView, index);
const def = tView.data[index] as DirectiveDef<any>; const def = tView.data[index] as DirectiveDef<any>;
const setInput = def.setInput; if (def.setInput !== null) {
if (setInput) {
def.setInput !(instance, value, publicName, privateName); def.setInput !(instance, value, publicName, privateName);
} else { } else {
instance[privateName] = value; instance[privateName] = value;

View File

@ -442,7 +442,7 @@ function updateDirectiveInputValue(
const inputs = tNode.inputs ![inputName] !; const inputs = tNode.inputs ![inputName] !;
const initialValue = getInitialStylingValue(context); const initialValue = getInitialStylingValue(context);
const value = normalizeStylingDirectiveInputValue(initialValue, newValue, isClassBased); const value = normalizeStylingDirectiveInputValue(initialValue, newValue, isClassBased);
setInputsForProperty(lView, inputs, value); setInputsForProperty(lView, inputs, inputName, value);
setElementExitFn(stylingApply); setElementExitFn(stylingApply);
} }
setValue(lView, bindingIndex, newValue); setValue(lView, bindingIndex, newValue);

View File

@ -738,10 +738,9 @@ export type PropertyAliases = {
* Store the runtime input or output names for all the directives. * Store the runtime input or output names for all the directives.
* *
* i+0: directive instance index * i+0: directive instance index
* i+1: publicName * i+1: privateName
* i+2: privateName
* *
* e.g. [0, 'change', 'change-minified'] * e.g. [0, 'change-minified']
*/ */
export type PropertyAliasValue = (number | string)[]; export type PropertyAliasValue = (number | string)[];