Skip to content

Commit 26c85fa

Browse files
committed
events: optimize EventTarget.addEventListener
1 parent d2ad9b4 commit 26c85fa

File tree

3 files changed

+61
-26
lines changed

3 files changed

+61
-26
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
4+
const bench = common.createBenchmark(main, {
5+
n: [1e5],
6+
nListener: [1, 5, 10],
7+
});
8+
9+
function main({ n, nListener }) {
10+
const target = new EventTarget();
11+
const listeners = [];
12+
for (let k = 0; k < nListener; k += 1)
13+
listeners.push(() => {});
14+
15+
bench.start();
16+
for (let i = 0; i < n; i += 1) {
17+
for (let k = listeners.length; --k >= 0;) {
18+
target.addEventListener('abort', listeners[k]);
19+
}
20+
for (let k = listeners.length; --k >= 0;) {
21+
target.removeEventListener('abort', listeners[k]);
22+
}
23+
}
24+
bench.end(n);
25+
}

benchmark/events/eventtarget-add-remove.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
const common = require('../common.js');
33

44
const bench = common.createBenchmark(main, {
5-
n: [1e6],
6-
nListener: [5, 10],
5+
n: [1e5],
6+
nListener: [1, 5, 10],
77
});
88

99
function main({ n, nListener }) {

lib/internal/event_target.js

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -596,21 +596,6 @@ class EventTarget {
596596
throw new ERR_INVALID_THIS('EventTarget');
597597
if (arguments.length < 2)
598598
throw new ERR_MISSING_ARGS('type', 'listener');
599-
600-
// We validateOptions before the validateListener check because the spec
601-
// requires us to hit getters.
602-
const {
603-
once,
604-
capture,
605-
passive,
606-
signal,
607-
isNodeStyleListener,
608-
weak,
609-
resistStopPropagation,
610-
} = validateEventListenerOptions(options);
611-
612-
validateAbortSignal(signal, 'options.signal');
613-
614599
if (!validateEventListener(listener)) {
615600
// The DOM silently allows passing undefined as a second argument
616601
// No error code for this since it is a Warning
@@ -623,19 +608,44 @@ class EventTarget {
623608
process.emitWarning(w);
624609
return;
625610
}
626-
type = webidl.converters.DOMString(type);
627611

628-
if (signal) {
629-
if (signal.aborted) {
630-
return;
612+
let once = false;
613+
let capture = false;
614+
let passive = false;
615+
let isNodeStyleListener = false;
616+
let weak = false;
617+
let resistStopPropagation = false;
618+
619+
if (options !== kEmptyObject) {
620+
// We validateOptions before the validateListener check because the spec
621+
// requires us to hit getters.
622+
options = validateEventListenerOptions(options);
623+
624+
once = options.once;
625+
capture = options.capture;
626+
passive = options.passive;
627+
isNodeStyleListener = options.isNodeStyleListener;
628+
weak = options.weak;
629+
resistStopPropagation = falsoptions.resistStopPropagation;
630+
631+
const signal = options.signal;
632+
633+
validateAbortSignal(signal, 'options.signal');
634+
635+
if (signal) {
636+
if (signal.aborted) {
637+
return;
638+
}
639+
// TODO(benjamingr) make this weak somehow? ideally the signal would
640+
// not prevent the event target from GC.
641+
signal.addEventListener('abort', () => {
642+
this.removeEventListener(type, listener, options);
643+
}, { __proto__: null, once: true, [kWeakHandler]: this, [kResistStopPropagation]: true });
631644
}
632-
// TODO(benjamingr) make this weak somehow? ideally the signal would
633-
// not prevent the event target from GC.
634-
signal.addEventListener('abort', () => {
635-
this.removeEventListener(type, listener, options);
636-
}, { __proto__: null, once: true, [kWeakHandler]: this, [kResistStopPropagation]: true });
637645
}
638646

647+
type = webidl.converters.DOMString(type);
648+
639649
let root = this[kEvents].get(type);
640650

641651
if (root === undefined) {

0 commit comments

Comments
 (0)