perf(ivy): guard host binding execution with a TNode flag (#33102)
Based on the results of the `directive_instantiate` executing host bindings logic (in creation mode) account for ~23% of time spent in the directive instantiation, even if a directive doesn't have host bindings! This is clearly wastful hence a new flag. PR Close #33102
This commit is contained in:
parent
dcca80bb1e
commit
d4d07233dc
|
@ -164,6 +164,7 @@ export const TNodeConstructor = class TNode implements ITNode {
|
||||||
if (this.flags & TNodeFlags.hasContentQuery) flags.push('TNodeFlags.hasContentQuery');
|
if (this.flags & TNodeFlags.hasContentQuery) flags.push('TNodeFlags.hasContentQuery');
|
||||||
if (this.flags & TNodeFlags.hasStyleInput) flags.push('TNodeFlags.hasStyleInput');
|
if (this.flags & TNodeFlags.hasStyleInput) flags.push('TNodeFlags.hasStyleInput');
|
||||||
if (this.flags & TNodeFlags.hasInitialStyling) flags.push('TNodeFlags.hasInitialStyling');
|
if (this.flags & TNodeFlags.hasInitialStyling) flags.push('TNodeFlags.hasInitialStyling');
|
||||||
|
if (this.flags & TNodeFlags.hasHostBindings) flags.push('TNodeFlags.hasHostBindings');
|
||||||
if (this.flags & TNodeFlags.isComponentHost) flags.push('TNodeFlags.isComponentHost');
|
if (this.flags & TNodeFlags.isComponentHost) flags.push('TNodeFlags.isComponentHost');
|
||||||
if (this.flags & TNodeFlags.isDirectiveHost) flags.push('TNodeFlags.isDirectiveHost');
|
if (this.flags & TNodeFlags.isDirectiveHost) flags.push('TNodeFlags.isDirectiveHost');
|
||||||
if (this.flags & TNodeFlags.isDetached) flags.push('TNodeFlags.isDetached');
|
if (this.flags & TNodeFlags.isDetached) flags.push('TNodeFlags.isDetached');
|
||||||
|
|
|
@ -536,7 +536,9 @@ export function createDirectivesInstances(
|
||||||
tView: TView, lView: LView, tNode: TElementNode | TContainerNode | TElementContainerNode) {
|
tView: TView, lView: LView, tNode: TElementNode | TContainerNode | TElementContainerNode) {
|
||||||
if (!getBindingsEnabled()) return;
|
if (!getBindingsEnabled()) return;
|
||||||
instantiateAllDirectives(tView, lView, tNode);
|
instantiateAllDirectives(tView, lView, tNode);
|
||||||
invokeDirectivesHostBindings(tView, lView, tNode);
|
if ((tNode.flags & TNodeFlags.hasHostBindings) === TNodeFlags.hasHostBindings) {
|
||||||
|
invokeDirectivesHostBindings(tView, lView, tNode);
|
||||||
|
}
|
||||||
setActiveHostElement(null);
|
setActiveHostElement(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,9 +1071,8 @@ export function resolveDirectives(
|
||||||
|
|
||||||
saveNameToExportMap(tView.data !.length - 1, def, exportsMap);
|
saveNameToExportMap(tView.data !.length - 1, def, exportsMap);
|
||||||
|
|
||||||
if (def.contentQueries) {
|
if (def.contentQueries !== null) tNode.flags |= TNodeFlags.hasContentQuery;
|
||||||
tNode.flags |= TNodeFlags.hasContentQuery;
|
if (def.hostBindings !== null) tNode.flags |= TNodeFlags.hasHostBindings;
|
||||||
}
|
|
||||||
|
|
||||||
// Init hooks are queued now so ngOnInit is called in host components before
|
// Init hooks are queued now so ngOnInit is called in host components before
|
||||||
// any projected components.
|
// any projected components.
|
||||||
|
|
|
@ -46,30 +46,37 @@ export const enum TNodeType {
|
||||||
*/
|
*/
|
||||||
export const enum TNodeFlags {
|
export const enum TNodeFlags {
|
||||||
/** This bit is set if the node is a host for any directive (including a component) */
|
/** This bit is set if the node is a host for any directive (including a component) */
|
||||||
isDirectiveHost = 0b00000001,
|
isDirectiveHost = 0b000000001,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This bit is set if the node is a host for a component. Setting this bit implies that the
|
* This bit is set if the node is a host for a component. Setting this bit implies that the
|
||||||
* isDirectiveHost bit is set as well. */
|
* isDirectiveHost bit is set as well. */
|
||||||
isComponentHost = 0b00000010,
|
isComponentHost = 0b000000010,
|
||||||
|
|
||||||
/** This bit is set if the node has been projected */
|
/** This bit is set if the node has been projected */
|
||||||
isProjected = 0b00000100,
|
isProjected = 0b000000100,
|
||||||
|
|
||||||
/** This bit is set if any directive on this node has content queries */
|
/** This bit is set if any directive on this node has content queries */
|
||||||
hasContentQuery = 0b00001000,
|
hasContentQuery = 0b000001000,
|
||||||
|
|
||||||
/** This bit is set if the node has any "class" inputs */
|
/** This bit is set if the node has any "class" inputs */
|
||||||
hasClassInput = 0b00010000,
|
hasClassInput = 0b000010000,
|
||||||
|
|
||||||
/** This bit is set if the node has any "style" inputs */
|
/** This bit is set if the node has any "style" inputs */
|
||||||
hasStyleInput = 0b00100000,
|
hasStyleInput = 0b000100000,
|
||||||
|
|
||||||
/** This bit is set if the node has initial styling */
|
/** This bit is set if the node has initial styling */
|
||||||
hasInitialStyling = 0b01000000,
|
hasInitialStyling = 0b001000000,
|
||||||
|
|
||||||
/** This bit is set if the node has been detached by i18n */
|
/** This bit is set if the node has been detached by i18n */
|
||||||
isDetached = 0b10000000,
|
isDetached = 0b010000000,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This bit is set if the node has directives with host bindings. This flags allows us to guard
|
||||||
|
* host-binding logic and invoke it only on nodes that actually have directives with host
|
||||||
|
* bindings.
|
||||||
|
*/
|
||||||
|
hasHostBindings = 0b100000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue