function LoopObservable() {
const listeners = new Set();
this.on = fn => listeners.add(fn);
this.off = fn => listeners.delete(fn);
this.clear = () => listeners.clear();
// This has bad failure modes.
this.send = function(message) {
for (let fn of listeners) {
try {
fn(message);
} catch (error) {
console.error(error);
}
}
};
};
function EventTargetObservable() {
// Name is arbitrary because we're using a dedicated object. Use a shorter
// name for shorter lookup.
const NAME = '.';
const __ = document.createTextNode(null);
this.on = function(handler) {
__.addEventListener(NAME, event => {
handler(event.detail);
});
};
this.off = function(handler) {
__.removeEventListener(NAME, handler);
};
this.send = function(detail) {
__.dispatchEvent(new CustomEvent(NAME, {
detail
}));
};
}
function run_test(observable, handlers = 5, calls = 1000) {
for (let i = 0; i < handlers; i++)
observable.on(message => console.log(i, message));
for (let i = 0; i < calls; i++)
observable.send({
type: "hello",
i
});
}
run_test(new LoopObservable());
run_test(new EventTargetObservable());
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
loop observable | |
EventTarget observable |
Test name | Executions per second |
---|---|
loop observable | 10.7 Ops/sec |
EventTarget observable | 12.1 Ops/sec |
Let's break down what's being tested on the provided JSON and explain the options, pros, cons, and other considerations.
Overview
The benchmark compares two approaches for implementing the "observable" pattern in JavaScript:
EventTarget
interface from a dummy object to dispatch events.Options being compared
In both cases, the test creates an observable object with methods to add and remove event handlers (on
and off
) and send events (send
). The main difference lies in how these methods are implemented:
EventTarget
object with an addEventListener
method that registers event listeners.Pros and Cons
EventListener
mechanism.EventTarget
object.Library and purpose
In this benchmark, the EventTarget
library is used to create an observable object that can dispatch events. The EventTarget
interface is a standard part of the DOM API in web browsers, providing a way to attach event listeners to objects.
The custom EventTargetObservable
class is created to hijack this interface and provide a more robust implementation for the observable pattern.
Special JS feature or syntax
In this benchmark, no special JavaScript features or syntax are used beyond standard ES6 syntax.
Other alternatives
If not using an EventTarget
-based approach, other alternatives could include:
However, these alternatives may introduce additional complexity and dependencies, making them less suitable for this benchmark.
Keep in mind that the choice of approach depends on the specific use case and requirements of the observable pattern implementation.