perf(ivy): attempt to coalesce listeners only in presence of directives (#29859)
PR Close #29859
This commit is contained in:
parent
d1d0f4a1ad
commit
6a1441f727
|
@ -14,7 +14,7 @@ import {GlobalTargetResolver, RElement, Renderer3, isProceduralRenderer} from '.
|
||||||
import {CLEANUP, FLAGS, LView, LViewFlags, RENDERER, TVIEW} from '../interfaces/view';
|
import {CLEANUP, FLAGS, LView, LViewFlags, RENDERER, TVIEW} from '../interfaces/view';
|
||||||
import {assertNodeOfPossibleTypes} from '../node_assert';
|
import {assertNodeOfPossibleTypes} from '../node_assert';
|
||||||
import {getLView, getPreviousOrParentTNode} from '../state';
|
import {getLView, getPreviousOrParentTNode} from '../state';
|
||||||
import {getComponentViewByIndex, getNativeByTNode, unwrapRNode} from '../util/view_utils';
|
import {getComponentViewByIndex, getNativeByTNode, hasDirectives, unwrapRNode} from '../util/view_utils';
|
||||||
import {BindingDirection, generatePropertyAliases, getCleanup, handleError, loadComponentRenderer, markViewDirty} from './shared';
|
import {BindingDirection, generatePropertyAliases, getCleanup, handleError, loadComponentRenderer, markViewDirty} from './shared';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,12 +132,16 @@ function listenerInternal(
|
||||||
// In order to have just one native event handler in presence of multiple handler functions,
|
// In order to have just one native event handler in presence of multiple handler functions,
|
||||||
// we just register a first handler function as a native event listener and then chain
|
// we just register a first handler function as a native event listener and then chain
|
||||||
// (coalesce) other handler functions on top of the first native handler function.
|
// (coalesce) other handler functions on top of the first native handler function.
|
||||||
//
|
let existingListener = null;
|
||||||
// Please note that the coalescing described here doesn't happen for events specifying an
|
// Please note that the coalescing described here doesn't happen for events specifying an
|
||||||
// alternative target (ex. (document:click)) - this is to keep backward compatibility with the
|
// alternative target (ex. (document:click)) - this is to keep backward compatibility with the
|
||||||
// view engine.
|
// view engine.
|
||||||
const existingListener =
|
// Also, we don't have to search for existing listeners is there are no directives
|
||||||
eventTargetResolver ? null : findExistingListener(lView, eventName, tNode.index);
|
// matching on a given node as we can't register multiple event handlers for the same event in
|
||||||
|
// a template (this would mean having duplicate attributes).
|
||||||
|
if (!eventTargetResolver && hasDirectives(tNode)) {
|
||||||
|
existingListener = findExistingListener(lView, eventName, tNode.index);
|
||||||
|
}
|
||||||
if (existingListener !== null) {
|
if (existingListener !== null) {
|
||||||
// Attach a new listener at the head of the coalesced listeners list.
|
// Attach a new listener at the head of the coalesced listeners list.
|
||||||
(<any>listenerFn).__ngNextListenerFn__ = (<any>existingListener).__ngNextListenerFn__;
|
(<any>listenerFn).__ngNextListenerFn__ = (<any>existingListener).__ngNextListenerFn__;
|
||||||
|
|
|
@ -131,6 +131,13 @@ export function getNativeByTNode(tNode: TNode, hostView: LView): RNode {
|
||||||
return unwrapRNode(hostView[tNode.index]);
|
return unwrapRNode(hostView[tNode.index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function that returns `true` if a given `TNode` has any matching directives.
|
||||||
|
*/
|
||||||
|
export function hasDirectives(tNode: TNode): boolean {
|
||||||
|
return tNode.directiveEnd > tNode.directiveStart;
|
||||||
|
}
|
||||||
|
|
||||||
export function getTNode(index: number, view: LView): TNode {
|
export function getTNode(index: number, view: LView): TNode {
|
||||||
ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
|
ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
|
||||||
ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
|
ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
|
||||||
|
|
|
@ -848,6 +848,9 @@
|
||||||
{
|
{
|
||||||
"name": "hasClassInput"
|
"name": "hasClassInput"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "hasDirectives"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "hasParentInjector"
|
"name": "hasParentInjector"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue