0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-21 13:09:21 +01:00

events: optimize EventTarget.addEventListener

PR-URL: https://github.com/nodejs/node/pull/55312
Fixes: https://github.com/nodejs/node/issues/55311
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Robert Nagy 2024-10-14 12:24:32 +02:00 committed by GitHub
parent f97865fab4
commit 488ce99d76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 25 deletions

View File

@ -0,0 +1,25 @@
'use strict';
const common = require('../common.js');
const bench = common.createBenchmark(main, {
n: [1e5],
nListener: [1, 5, 10],
});
function main({ n, nListener }) {
const target = new EventTarget();
const listeners = [];
for (let k = 0; k < nListener; k += 1)
listeners.push(() => {});
bench.start();
for (let i = 0; i < n; i += 1) {
for (let k = listeners.length; --k >= 0;) {
target.addEventListener('abort', listeners[k]);
}
for (let k = listeners.length; --k >= 0;) {
target.removeEventListener('abort', listeners[k]);
}
}
bench.end(n);
}

View File

@ -2,8 +2,8 @@
const common = require('../common.js');
const bench = common.createBenchmark(main, {
n: [1e6],
nListener: [5, 10],
n: [1e5],
nListener: [1, 5, 10],
});
function main({ n, nListener }) {

View File

@ -597,19 +597,40 @@ class EventTarget {
if (arguments.length < 2)
throw new ERR_MISSING_ARGS('type', 'listener');
// We validateOptions before the validateListener check because the spec
// requires us to hit getters.
const {
once,
capture,
passive,
signal,
isNodeStyleListener,
weak,
resistStopPropagation,
} = validateEventListenerOptions(options);
let once = false;
let capture = false;
let passive = false;
let isNodeStyleListener = false;
let weak = false;
let resistStopPropagation = false;
validateAbortSignal(signal, 'options.signal');
if (options !== kEmptyObject) {
// We validateOptions before the validateListener check because the spec
// requires us to hit getters.
options = validateEventListenerOptions(options);
once = options.once;
capture = options.capture;
passive = options.passive;
isNodeStyleListener = options.isNodeStyleListener;
weak = options.weak;
resistStopPropagation = options.resistStopPropagation;
const signal = options.signal;
validateAbortSignal(signal, 'options.signal');
if (signal) {
if (signal.aborted) {
return;
}
// TODO(benjamingr) make this weak somehow? ideally the signal would
// not prevent the event target from GC.
signal.addEventListener('abort', () => {
this.removeEventListener(type, listener, options);
}, { __proto__: null, once: true, [kWeakHandler]: this, [kResistStopPropagation]: true });
}
}
if (!validateEventListener(listener)) {
// The DOM silently allows passing undefined as a second argument
@ -623,18 +644,8 @@ class EventTarget {
process.emitWarning(w);
return;
}
type = webidl.converters.DOMString(type);
if (signal) {
if (signal.aborted) {
return;
}
// TODO(benjamingr) make this weak somehow? ideally the signal would
// not prevent the event target from GC.
signal.addEventListener('abort', () => {
this.removeEventListener(type, listener, options);
}, { __proto__: null, once: true, [kWeakHandler]: this, [kResistStopPropagation]: true });
}
type = webidl.converters.DOMString(type);
let root = this[kEvents].get(type);