feat: performance improvement for eventListeners (#34613)

PR Close #34613
This commit is contained in:
JiaLiPassion 2020-01-02 22:59:20 +09:00 committed by Miško Hevery
parent 4d36b2f6e9
commit a3c7ab99b7

View File

@ -44,6 +44,16 @@ export const globalSources: any = {};
const EVENT_NAME_SYMBOL_REGX = new RegExp('^' + ZONE_SYMBOL_PREFIX + '(\\w+)(true|false)$'); const EVENT_NAME_SYMBOL_REGX = new RegExp('^' + ZONE_SYMBOL_PREFIX + '(\\w+)(true|false)$');
const IMMEDIATE_PROPAGATION_SYMBOL = zoneSymbol('propagationStopped'); const IMMEDIATE_PROPAGATION_SYMBOL = zoneSymbol('propagationStopped');
function prepareEventNames(eventName: string, eventNameToString?: (eventName: string) => string) {
const falseEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
const trueEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
zoneSymbolEventNames[eventName] = {};
zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
}
export interface PatchEventTargetOptions { export interface PatchEventTargetOptions {
// validateHandler // validateHandler
vh?: (nativeDelegate: any, delegate: any, target: any, args: any) => boolean; vh?: (nativeDelegate: any, delegate: any, target: any, args: any) => boolean;
@ -387,23 +397,12 @@ export function patchEventTarget(
} }
const zone = Zone.current; const zone = Zone.current;
const symbolEventNames = zoneSymbolEventNames[eventName]; let symbolEventNames = zoneSymbolEventNames[eventName];
let symbolEventName;
if (!symbolEventNames) { if (!symbolEventNames) {
// the code is duplicate, but I just want to get some better performance prepareEventNames(eventName, eventNameToString);
const falseEventName = symbolEventNames = zoneSymbolEventNames[eventName];
(eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
const trueEventName =
(eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
zoneSymbolEventNames[eventName] = {};
zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
symbolEventName = capture ? symbolCapture : symbol;
} else {
symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
} }
const symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
let existingTasks = target[symbolEventName]; let existingTasks = target[symbolEventName];
let isExisting = false; let isExisting = false;
if (existingTasks) { if (existingTasks) {
@ -668,20 +667,35 @@ export function patchEventTarget(
} }
export function findEventTasks(target: any, eventName: string): Task[] { export function findEventTasks(target: any, eventName: string): Task[] {
const foundTasks: any[] = []; if (!eventName) {
for (let prop in target) { const foundTasks: any[] = [];
const match = EVENT_NAME_SYMBOL_REGX.exec(prop); for (let prop in target) {
let evtName = match && match[1]; const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
if (evtName && (!eventName || evtName === eventName)) { let evtName = match && match[1];
const tasks: any = target[prop]; if (evtName && (!eventName || evtName === eventName)) {
if (tasks) { const tasks: any = target[prop];
for (let i = 0; i < tasks.length; i++) { if (tasks) {
foundTasks.push(tasks[i]); for (let i = 0; i < tasks.length; i++) {
foundTasks.push(tasks[i]);
}
} }
} }
} }
return foundTasks;
}
let symbolEventName = zoneSymbolEventNames[eventName];
if (!symbolEventName) {
prepareEventNames(eventName);
symbolEventName = zoneSymbolEventNames[eventName];
}
const captureFalseTasks = target[symbolEventName[FALSE_STR]];
const captureTrueTasks = target[symbolEventName[TRUE_STR]];
if (!captureFalseTasks) {
return captureTrueTasks ? captureTrueTasks.slice() : [];
} else {
return captureTrueTasks ? captureFalseTasks.concat(captureTrueTasks) :
captureFalseTasks.slice();
} }
return foundTasks;
} }
export function patchEventPrototype(global: any, api: _ZonePrivate) { export function patchEventPrototype(global: any, api: _ZonePrivate) {