Events Benchmarks
Compare event handling and subscription management performance across libraries.
What This Benchmark Measures
This benchmark tests event handling overhead — how much cost each library adds on top of native EventTarget.
Each scenario:
- Creates a recursive chain of
EventTargetlisteners (depth configurable, default 100) - Dispatches 100 events at the root
- Each layer forwards events to its child
EventTarget - Triggers cancellation to tear down all listeners at every level
Fair Comparison: All Libraries Use Native EventTarget
| Library | Event Source | Subscription API | Cleanup |
|---|---|---|---|
| addEventListener | EventTarget |
Native addEventListener |
removeEventListener on abort |
| effection | EventTarget |
on() + each() |
Structured concurrency (halt) |
| rxjs | EventTarget |
fromEvent() |
unsubscribe() via takeUntil |
| effect | EventTarget |
Stream.fromEventListener() |
Fiber interruption |
The addEventListener baseline shows the raw cost of native event handling with manual cleanup. The reactive libraries add abstraction for:
- Automatic cleanup — listeners removed when cancelled
- Subscription tracking — knowing what's active
- Composability — transforming/chaining event streams
The benchmark measures how much overhead each abstraction adds.
Libraries compared: effection, rxjs, effect, addEventListener
Source Code
View the benchmark implementations on GitHub:
Library Comparison
Average latency comparison across all libraries for the selected Effection release.
Showing data for release on
Percentile Comparison
Performance Over Releases
How each library's performance has changed across Effection releases.
Runtime Comparison
Compare performance across runtimes for each library.