From 188fc2bec0da8fb498dc6034972f20c832dc52da Mon Sep 17 00:00:00 2001 From: wenxingluo Date: Thu, 25 Dec 2025 21:32:17 +0800 Subject: [PATCH 1/2] perf: optimize proto listener perf, considering that the same node type shares the same listners --- src/Node.ts | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Node.ts b/src/Node.ts index c68a8f93..e62d0868 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -2500,24 +2500,34 @@ export abstract class Node { } } + static protoListenerMap = new Map(); + _getProtoListeners(eventType) { - const allListeners = this._cache.get(ALL_LISTENERS) ?? {}; - let events = allListeners?.[eventType]; - if (events === undefined) { - //recalculate cache - events = []; + const { nodeType } = this; + let listeners = Node.protoListenerMap.get(nodeType); + // if no cache for listeners, we need to pre calculate it + if (!listeners) { + listeners = {}; let obj = Object.getPrototypeOf(this); while (obj) { - const hierarchyEvents = obj.eventListeners?.[eventType] ?? []; - events.push(...hierarchyEvents); + if (!obj.eventListeners) { + obj = Object.getPrototypeOf(obj); + continue; + } + if (obj.hasOwnProperty('eventListeners')) { + for (var event in obj.eventListeners) { + const newEvents = obj.eventListeners[event]; + const oldEvents = listeners[event] || []; + + listeners[event] = newEvents.concat(oldEvents); + } + } obj = Object.getPrototypeOf(obj); } - // update cache - allListeners[eventType] = events; - this._cache.set(ALL_LISTENERS, allListeners); + Node.protoListenerMap.set(nodeType, listeners); } - return events; + return listeners[eventType]; } _fire(eventType, evt) { evt = evt || {}; From f4bc2e1bf509f204b2902bd04f8e5d99baf599d5 Mon Sep 17 00:00:00 2001 From: wenxingluo Date: Thu, 25 Dec 2025 22:21:23 +0800 Subject: [PATCH 2/2] fix: revert to master latest --- src/Node.ts | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/Node.ts b/src/Node.ts index e62d0868..3d824f86 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -2503,31 +2503,24 @@ export abstract class Node { static protoListenerMap = new Map(); _getProtoListeners(eventType) { - const { nodeType } = this; - let listeners = Node.protoListenerMap.get(nodeType); - // if no cache for listeners, we need to pre calculate it - if (!listeners) { - listeners = {}; + const { nodeType } = this; + const allListeners = Node.protoListenerMap.get(nodeType) || {}; + let events = allListeners?.[eventType]; + if (events === undefined) { + //recalculate cache + events = []; let obj = Object.getPrototypeOf(this); while (obj) { - if (!obj.eventListeners) { - obj = Object.getPrototypeOf(obj); - continue; - } - if (obj.hasOwnProperty('eventListeners')) { - for (var event in obj.eventListeners) { - const newEvents = obj.eventListeners[event]; - const oldEvents = listeners[event] || []; - - listeners[event] = newEvents.concat(oldEvents); - } - } + const hierarchyEvents = obj.eventListeners?.[eventType] ?? []; + events.push(...hierarchyEvents); obj = Object.getPrototypeOf(obj); } - Node.protoListenerMap.set(nodeType, listeners); + // update cache + allListeners[eventType] = events; + Node.protoListenerMap.set(nodeType, allListeners); } - return listeners[eventType]; + return events; } _fire(eventType, evt) { evt = evt || {};