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)
fn(message);
};
};
function EventTargetObservable() {
// Name is arbitrary because we're using a dedicated object. Use a shorter
// name for shorter lookup.
const NAME = '.';
const __ = new EventTarget()
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 = 2, 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 | 7.6 Ops/sec |
EventTarget observable | 5.6 Ops/sec |
What is tested on the provided JSON?
The provided JSON represents two JavaScript microbenchmarks that test the performance of different approaches to implement an observable pattern in JavaScript.
The first benchmark, "loop observable", tests the implementation of an observable pattern using a loop over callbacks. The second benchmark, "EventTarget observable", tests the implementation of an observable pattern using the built-in EventTarget
interface.
What options are compared?
The two benchmarks compare the following options:
EventTarget
implementation from a dummy object and uses it to dispatch events to registered listeners.Pros and Cons of each approach:
Loop over callbacks:
Pros:
Cons:
EventTarget implementation:
Pros:
Cons:
EventTarget
interface.Library used:
The EventTargetObservable
benchmark uses a library called EventTarget
. This is a dedicated object that provides an implementation of the EventTarget
interface, which can be hijacked by the benchmark. The purpose of this library is to provide a simple way to implement event dispatching without having to create a custom implementation from scratch.
Special JS feature or syntax:
The benchmarks use several special JavaScript features and syntax:
EventTargetObservable
benchmark uses custom events to dispatch messages between the observable and its listeners.Set
and array methods (e.g., addEventListener
, removeEventListener
) to manage the registered listeners.Other alternatives:
If you wanted to implement an observable pattern in JavaScript without using a library like EventTarget
, you could consider alternative approaches such as:
However, these alternatives may have trade-offs in terms of complexity, performance, and ease of use.