perf(ivy): avoid generating extra parameters for host property bindings (#31550)
Currently we reuse the same instruction both for regular property bindings and property bindings on the `host`. The only difference between the two is that when it's on the host we shouldn't support inputs. We have an optional parameter called `nativeOnly` which is used to differentiate the two, however since `nativeOnly` is preceeded by another optional parameter (`sanitizer`), we have to generate two extra parameters for each host property bindings every time (e.g. `property('someProp', 'someValue', null, true)`). These changes add a new instruction called `hostProperty` which avoids the need for the two parameters by removing `nativeOnly` which is always set and it allows us to omit `sanitizer` when it isn't being used. These changes also remove the `nativeOnly` parameter from the `updateSyntheticHostBinding` instruction, because it's only generated for host elements which means that we can assume that its value will always be `true`. PR Close #31550
This commit is contained in:
@ -98,6 +98,7 @@ export {
|
||||
ɵɵcontentQuery,
|
||||
ɵɵloadContentQuery,
|
||||
ɵɵelementEnd,
|
||||
ɵɵhostProperty,
|
||||
ɵɵproperty,
|
||||
ɵɵpropertyInterpolate,
|
||||
ɵɵpropertyInterpolate1,
|
||||
|
@ -82,6 +82,7 @@ export {
|
||||
|
||||
ɵɵprojection,
|
||||
ɵɵprojectionDef,
|
||||
ɵɵhostProperty,
|
||||
ɵɵproperty,
|
||||
ɵɵpropertyInterpolate,
|
||||
ɵɵpropertyInterpolate1,
|
||||
|
@ -49,3 +49,4 @@ export * from './text';
|
||||
export * from './text_interpolation';
|
||||
export * from './class_map_interpolation';
|
||||
export * from './style_prop_interpolation';
|
||||
export * from './host_property';
|
||||
|
73
packages/core/src/render3/instructions/host_property.ts
Normal file
73
packages/core/src/render3/instructions/host_property.ts
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. 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
|
||||
*/
|
||||
import {assertNotEqual} from '../../util/assert';
|
||||
import {SanitizerFn} from '../interfaces/sanitization';
|
||||
import {getLView, getSelectedIndex} from '../state';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
import {bind} from './property';
|
||||
import {TsickleIssue1009, elementPropertyInternal, loadComponentRenderer} from './shared';
|
||||
|
||||
/**
|
||||
* Update a property on a host element. Only applies to native node properties, not inputs.
|
||||
*
|
||||
* Operates on the element selected by index via the {@link select} instruction.
|
||||
*
|
||||
* @param propName Name of property. Because it is going to DOM, this is not subject to
|
||||
* renaming as part of minification.
|
||||
* @param value New value to write.
|
||||
* @param sanitizer An optional function used to sanitize the value.
|
||||
* @returns This function returns itself so that it may be chained
|
||||
* (e.g. `property('name', ctx.name)('title', ctx.title)`)
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵhostProperty<T>(
|
||||
propName: string, value: T, sanitizer?: SanitizerFn | null): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
ngDevMode && assertNotEqual(index, -1, 'selected index cannot be -1');
|
||||
const lView = getLView();
|
||||
const bindReconciledValue = bind(lView, value);
|
||||
if (bindReconciledValue !== NO_CHANGE) {
|
||||
elementPropertyInternal(index, propName, bindReconciledValue, sanitizer, true);
|
||||
}
|
||||
return ɵɵhostProperty;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates a synthetic host binding (e.g. `[@foo]`) on a component.
|
||||
*
|
||||
* This instruction is for compatibility purposes and is designed to ensure that a
|
||||
* synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
|
||||
* the component's renderer. Normally all host bindings are evaluated with the parent
|
||||
* component's renderer, but, in the case of animation @triggers, they need to be
|
||||
* evaluated with the sub component's renderer (because that's where the animation
|
||||
* triggers are defined).
|
||||
*
|
||||
* Do not use this instruction as a replacement for `elementProperty`. This instruction
|
||||
* only exists to ensure compatibility with the ViewEngine's host binding behavior.
|
||||
*
|
||||
* @param index The index of the element to update in the data array
|
||||
* @param propName Name of property. Because it is going to DOM, this is not subject to
|
||||
* renaming as part of minification.
|
||||
* @param value New value to write.
|
||||
* @param sanitizer An optional function used to sanitize the value.
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵupdateSyntheticHostBinding<T>(
|
||||
propName: string, value: T | NO_CHANGE, sanitizer?: SanitizerFn | null): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(benlesh): remove bind call here.
|
||||
const bound = bind(lView, value);
|
||||
if (bound !== NO_CHANGE) {
|
||||
elementPropertyInternal(index, propName, bound, sanitizer, true, loadComponentRenderer);
|
||||
}
|
||||
return ɵɵupdateSyntheticHostBinding;
|
||||
}
|
@ -12,7 +12,7 @@ import {BINDING_INDEX, LView} from '../interfaces/view';
|
||||
import {getLView, getSelectedIndex} from '../state';
|
||||
import {NO_CHANGE} from '../tokens';
|
||||
|
||||
import {TsickleIssue1009, elementPropertyInternal, loadComponentRenderer, storeBindingMetadata} from './shared';
|
||||
import {TsickleIssue1009, elementPropertyInternal, storeBindingMetadata} from './shared';
|
||||
|
||||
|
||||
/**
|
||||
@ -28,22 +28,19 @@ import {TsickleIssue1009, elementPropertyInternal, loadComponentRenderer, storeB
|
||||
* renaming as part of minification.
|
||||
* @param value New value to write.
|
||||
* @param sanitizer An optional function used to sanitize the value.
|
||||
* @param nativeOnly Whether or not we should only set native properties and skip input check
|
||||
* (this is necessary for host property bindings)
|
||||
* @returns This function returns itself so that it may be chained
|
||||
* (e.g. `property('name', ctx.name)('title', ctx.title)`)
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵproperty<T>(
|
||||
propName: string, value: T, sanitizer?: SanitizerFn | null,
|
||||
nativeOnly?: boolean): TsickleIssue1009 {
|
||||
propName: string, value: T, sanitizer?: SanitizerFn | null): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
ngDevMode && assertNotEqual(index, -1, 'selected index cannot be -1');
|
||||
const lView = getLView();
|
||||
const bindReconciledValue = bind(lView, value);
|
||||
if (bindReconciledValue !== NO_CHANGE) {
|
||||
elementPropertyInternal(index, propName, bindReconciledValue, sanitizer, nativeOnly);
|
||||
elementPropertyInternal(index, propName, bindReconciledValue, sanitizer);
|
||||
}
|
||||
return ɵɵproperty;
|
||||
}
|
||||
@ -59,39 +56,3 @@ export function bind<T>(lView: LView, value: T): T|NO_CHANGE {
|
||||
storeBindingMetadata(lView);
|
||||
return bindingUpdated(lView, bindingIndex, value) ? value : NO_CHANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a synthetic host binding (e.g. `[@foo]`) on a component.
|
||||
*
|
||||
* This instruction is for compatibility purposes and is designed to ensure that a
|
||||
* synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
|
||||
* the component's renderer. Normally all host bindings are evaluated with the parent
|
||||
* component's renderer, but, in the case of animation @triggers, they need to be
|
||||
* evaluated with the sub component's renderer (because that's where the animation
|
||||
* triggers are defined).
|
||||
*
|
||||
* Do not use this instruction as a replacement for `elementProperty`. This instruction
|
||||
* only exists to ensure compatibility with the ViewEngine's host binding behavior.
|
||||
*
|
||||
* @param index The index of the element to update in the data array
|
||||
* @param propName Name of property. Because it is going to DOM, this is not subject to
|
||||
* renaming as part of minification.
|
||||
* @param value New value to write.
|
||||
* @param sanitizer An optional function used to sanitize the value.
|
||||
* @param nativeOnly Whether or not we should only set native properties and skip input check
|
||||
* (this is necessary for host property bindings)
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵupdateSyntheticHostBinding<T>(
|
||||
propName: string, value: T | NO_CHANGE, sanitizer?: SanitizerFn | null,
|
||||
nativeOnly?: boolean): TsickleIssue1009 {
|
||||
const index = getSelectedIndex();
|
||||
const lView = getLView();
|
||||
// TODO(benlesh): remove bind call here.
|
||||
const bound = bind(lView, value);
|
||||
if (bound !== NO_CHANGE) {
|
||||
elementPropertyInternal(index, propName, bound, sanitizer, nativeOnly, loadComponentRenderer);
|
||||
}
|
||||
return ɵɵupdateSyntheticHostBinding;
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ export const angularCoreEnv: {[name: string]: Function} =
|
||||
'ɵɵpipeBind4': r3.ɵɵpipeBind4,
|
||||
'ɵɵpipeBindV': r3.ɵɵpipeBindV,
|
||||
'ɵɵprojectionDef': r3.ɵɵprojectionDef,
|
||||
'ɵɵhostProperty': r3.ɵɵhostProperty,
|
||||
'ɵɵproperty': r3.ɵɵproperty,
|
||||
'ɵɵpropertyInterpolate': r3.ɵɵpropertyInterpolate,
|
||||
'ɵɵpropertyInterpolate1': r3.ɵɵpropertyInterpolate1,
|
||||
|
Reference in New Issue
Block a user