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:
parent
5aec1798eb
commit
da0c372fdf
|
@ -1021,7 +1021,7 @@ function i18nAttributesFirstPass(lView: LView, tView: TView, index: number, valu
|
|||
// Check if that attribute is a directive input
|
||||
const dataValue = tNode.inputs && tNode.inputs[attrName];
|
||||
if (dataValue) {
|
||||
setInputsForProperty(lView, dataValue, value);
|
||||
setInputsForProperty(lView, dataValue, attrName, value);
|
||||
if (ngDevMode) {
|
||||
const element = getNativeByIndex(previousElementIndex, lView) as RElement | RComment;
|
||||
setNgReflectProperties(lView, element, tNode.type, dataValue, value);
|
||||
|
|
|
@ -134,11 +134,11 @@ export function ɵɵelementEnd(): void {
|
|||
|
||||
if (hasClassInput(tNode)) {
|
||||
const inputName: string = selectClassBasedInputName(tNode.inputs !);
|
||||
setDirectiveStylingInput(tNode.classes, lView, tNode.inputs ![inputName]);
|
||||
setDirectiveStylingInput(tNode.classes, lView, tNode.inputs ![inputName], inputName);
|
||||
}
|
||||
|
||||
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(
|
||||
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
|
||||
// event that the value does not exist at all. For this reason
|
||||
// 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
|
||||
// is applied during creation mode. This is a deviation from VE and should
|
||||
// be (Jira Issue = FW-1467).
|
||||
setInputsForProperty(lView, stylingInputs, value);
|
||||
setInputsForProperty(lView, stylingInputs, propName, value);
|
||||
}
|
||||
|
||||
function validateElement(
|
||||
|
|
|
@ -196,10 +196,10 @@ function listenerInternal(
|
|||
const propsLength = props.length;
|
||||
if (propsLength) {
|
||||
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;
|
||||
ngDevMode && assertDataInRange(lView, index);
|
||||
const minifiedName = props[i + 2];
|
||||
const minifiedName = props[i + 1];
|
||||
const directiveInstance = lView[index];
|
||||
const output = directiveInstance[minifiedName];
|
||||
|
||||
|
|
|
@ -848,9 +848,9 @@ function generatePropertyAliases(
|
|||
const internalName = inputAliasMap[publicName];
|
||||
|
||||
if (propStore.hasOwnProperty(publicName)) {
|
||||
propStore[publicName].push(directiveDefIdx, publicName, internalName);
|
||||
propStore[publicName].push(directiveDefIdx, internalName);
|
||||
} else {
|
||||
(propStore[publicName] = [directiveDefIdx, publicName, internalName]);
|
||||
(propStore[publicName] = [directiveDefIdx, internalName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ export function elementPropertyInternal<T>(
|
|||
let inputData = tNode.inputs;
|
||||
let dataValue: PropertyAliasValue|undefined;
|
||||
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 (ngDevMode) {
|
||||
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:
|
||||
* i+0: directive instance index
|
||||
* i+1: publicName
|
||||
* i+2: privateName
|
||||
* i+1: privateName
|
||||
*
|
||||
* 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) {
|
||||
setNgReflectProperty(lView, element, type, dataValue[i + 2] as string, value);
|
||||
for (let i = 0; i < dataValue.length; i += 2) {
|
||||
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.
|
||||
* @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];
|
||||
for (let i = 0; i < inputs.length;) {
|
||||
const index = inputs[i++] as number;
|
||||
const publicName = inputs[i++] as string;
|
||||
const privateName = inputs[i++] as string;
|
||||
const instance = lView[index];
|
||||
ngDevMode && assertDataInRange(lView, index);
|
||||
const def = tView.data[index] as DirectiveDef<any>;
|
||||
const setInput = def.setInput;
|
||||
if (setInput) {
|
||||
if (def.setInput !== null) {
|
||||
def.setInput !(instance, value, publicName, privateName);
|
||||
} else {
|
||||
instance[privateName] = value;
|
||||
|
|
|
@ -442,7 +442,7 @@ function updateDirectiveInputValue(
|
|||
const inputs = tNode.inputs ![inputName] !;
|
||||
const initialValue = getInitialStylingValue(context);
|
||||
const value = normalizeStylingDirectiveInputValue(initialValue, newValue, isClassBased);
|
||||
setInputsForProperty(lView, inputs, value);
|
||||
setInputsForProperty(lView, inputs, inputName, value);
|
||||
setElementExitFn(stylingApply);
|
||||
}
|
||||
setValue(lView, bindingIndex, newValue);
|
||||
|
|
|
@ -738,10 +738,9 @@ export type PropertyAliases = {
|
|||
* Store the runtime input or output names for all the directives.
|
||||
*
|
||||
* i+0: directive instance index
|
||||
* i+1: publicName
|
||||
* i+2: privateName
|
||||
* i+1: privateName
|
||||
*
|
||||
* e.g. [0, 'change', 'change-minified']
|
||||
* e.g. [0, 'change-minified']
|
||||
*/
|
||||
export type PropertyAliasValue = (number | string)[];
|
||||
|
||||
|
|
Loading…
Reference in New Issue