From 4a4c15072bf845a2086a52c19e7015b4b9225f42 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Tue, 8 Oct 2024 08:36:33 +0200 Subject: [PATCH] events: optimize EventTarget.addEventListener --- benchmark/events/eventtarget-add-remove.js | 4 +- lib/internal/event_target.js | 58 +++++++++++++--------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/benchmark/events/eventtarget-add-remove.js b/benchmark/events/eventtarget-add-remove.js index a3defce03cfb8d..62048086d5d0bf 100644 --- a/benchmark/events/eventtarget-add-remove.js +++ b/benchmark/events/eventtarget-add-remove.js @@ -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 }) { diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index aa0203b930fbe8..f53e38965b10f2 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -596,21 +596,6 @@ class EventTarget { throw new ERR_INVALID_THIS('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); - - validateAbortSignal(signal, 'options.signal'); - if (!validateEventListener(listener)) { // The DOM silently allows passing undefined as a second argument // No error code for this since it is a Warning @@ -623,17 +608,42 @@ class EventTarget { process.emitWarning(w); return; } - type = webidl.converters.DOMString(type); - if (signal) { - if (signal.aborted) { - return; + let once = false + let capture = false + let passive = false + let isNodeStyleListener = false + let weak = false + let resistStopPropagation = false + + 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 = falsoptions.resistStopPropagation; + + const signal = options.signal; + + validateAbortSignal(signal, 'options.signal'); + + 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 }); } - // 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 }); } let root = this[kEvents].get(type);