Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does multiple listeners for the same window events affect performance?

In a web project I'm using multiple listeners for the same window events.

window.addevntlistener("resize", callback)
window.addevntlistener("hasChange", callback)

I assume adding multiple event listeners on the window has a negligible effect in terms of performance. Is it so, or should I just listen once, and add a my own javascript subscribing solution for the various units which need to be notified?

The resize listener could be used by a basic UI element which is rendered in a list, and therefor add hundreds of listeners.

Edit: I'm aware of Does adding too many event listeners affect performance? . However, that refers to a element click events. In that case there are multiple listeners to multiple objects. In my case there are multiple listeners to the same object, and a special object - the window.

like image 828
Ben Carp Avatar asked Jan 04 '20 05:01

Ben Carp


1 Answers

In Javascript you have an event loop. The mechanism consists of a loop, which represents the plan to call certain functions in a given order. However, user event, such as click or resize cannot be planned before it happens. As a result, there is also a message queue (also called callback queue), where your events are waiting to be executed.

enter image description here

When the event queue runs out of functions to be executed, the message queue's items start to be processed. At this point your events will be processed.

Basically we are talking of a forever loop where you put some functions. Of course it affects performance, because everything to be done affects the performance versus the case when it is not done. However, this in most cases does not mean a meaningful difference in any way that could be felt.

If we assume that the functions you associate with these events is of very low (maybe constant) complexity, then we still have a linear complexity due to the event loop and you would have to add MANY events to this loop to have any performance difference that could be felt.

However, if the functions that you add are very complex, that will significantly decrease performance and note, Javascript is (mostly) single-threaded. So, if you experience performance issues, then you need to check the complexity of your functions first.

It is worth noting that your event handlers will only be executed when the given event is triggered, probably by the user. So, if you add a million of resize handlers, by themselves they will not affect performance (except at the time when they are added, but that's insignificant), but when a resize happens, all your event handlers attached to this event will be executed.

So, if you experience performance issues at a given event, then you will need to analyze the event handlers associated to that event. If your event handlers are too many or too complex, then you can use web workers (which are running in separate threads) to execute the more time-consuming jobs, so your UI will remain responsive in terms of handling events.

EDIT

This is how one can test the two scenarios. In this code we will assume that event is a String variable, which can be a click, a key event or anything.

Measurement functionality

var count = 1000; //you can change this value whenever you need
var startDate;
var endDate;
var diff;

function happened() {
    if (!startDate) startDate = performance.now();
    if (!(--count)) {
        endDate = performance.now();
        diff = endDate - startDate; //in milliseconds
        console.log(diff);
    }
}

Many Listeners

for (var i = 0; i < count; i++) window.addEventListener("resize", function() {happened()});

61 milliseconds in my test (event was "resize" in my case)

Single listener

window.addEventListener("resize", function() {
    while (count > 0) happened();
});

55 milliseconds in my test (event was "resize" in my case)

like image 76
Lajos Arpad Avatar answered Oct 28 '22 13:10

Lajos Arpad