Should I always removeEventListener? - javascript

Say I add a load event to the window like so:
window.addEventListener("load",initialize);
Should I then remove the load event listener from the window after the event is fired? It only fires once, but will it continue to listen after that happens?
It's simple enough to do:
function initialize(event_){
/* Just by adding this line. */
window.removeEventListener("load",initialize);
}
But is that overkill or will that actually benefit the performance of my program? I only ask because the "load" event only fires once, so it would make sense if it just resolved itself. I've never heard of a self resolving listener, though... Any thoughts?
Edit: Also, I'm not concerned specifically with the "load" event, just the general scenario where the listener continues to listen for an event that only fires once.

window.addEventListener('load', initialize, {once: true});

Should I then remove the load event listener from the window after the event is fired?
I've never seen that done, so I don't think there's a real need for it.
It only fires once, but will it continue to listen after that happens?
It is only fired once by the DOM, yes. But it will continue to listen, you could easily trigger a load event manually (see MDN for examples).
But is that overkill or will that actually benefit the performance of my program?
Typically it's overkill, as this doesn't make a huge difference. Of course, it might trigger garbage collection on initialize, which could save a bit of memory (or more, depending on your code structure) and improve performance by making it available to the rest of your app.

Related

Throttling events - Perfomance implications of adding and removing event listeners

This isn't a problem I'm having - it's more just a general interest query.
I've just implemented throttling on scroll events on my web app. I've done it in the way all tutorials teach you i.e. inside your function, you block the rest of its execution using some timer controlled variable which makes you wait until the function can be run again.
My question is this: surely in this case, on every scroll event, the function is still being run, it's just that the function is quickly exited so it doesn't take much of a performance hit.
I'm surprised that the standard correct way to throttle events isn't something like:
Add an event listener that runs a function.
When event occurs, run the function, remove the event listener and then set up a timeout to re-add the event listener at a later time.
I presume people far cleverer than me have thought of this and there are good reasons why not to do this.
Is it because it's unnecessarily fiddly? Is it much more processor intensive to add and remove listeners than it is to run empty functions?
I'm just curious. Thanks.
Neither of those is a performance concern. Starting to run a function and then bailing out is very cheap, and so too is adding/removing event listeners. So if you have a situation that can be solved by adding and removing event listeners, and it's easier to under than the other options, feel free to do it.
I can think of a couple reasons why i wouldn't do it though
It's narrow. There are very few problems that can be solved by removing an event listener. Throttling, yes, but even a very similar feature -- debouncing -- can't be done by removing the event listener. (Debouncing means to wait until there's a period of inactivity. So if the function keeps getting called quickly, you'll keep delaying longer. If you remove the event listener, you lose the ability to know that you need to wait longer)
You have to know how to tear down and set up the event listener. For your case that may be fine, but a general-purpose throttle utility (Eg, lodash's throttle function) may have no idea how the function is going to be called. If you use the setTimeout approach instead, then it will work regardless of how it's being called.

Event Listeners Efficiency

How do event listeners in any programming language actually work internally?
The point of this post is to get an overall idea of how event listeners in general work. A while back, when I first started playing with Javascript and Html, every time I needed to create a button to perform an action, lets say execute function 'my_func();', I would simply go...
<button onclick="my_func();">Click me</button>
That is just wonderful, a button, staying idle for the majority of the time, except when clicked. Then, it would execute the corresponding function.
Then I came across Event Listeners. Basically, an event listener is a procedure or function in a computer program that waits for an event to occur.
The first thing that came into my mind was the following: When you create an event listener, does that basically just create an infinite loop that checks whether something has been triggered or not? Isn't this inefficient if you have dozens or hundreds of events to listen for? Hundreds of loops checking for a different specific condition every second? Why would you use this instead of the beautiful 'onclick'?
I will proceed to post the answers that I found, (not in StackOverflow, that's why I decided to post it here, so as to enlarge the already vast content of this site). This answer, of all the ones I read, was the one that convinced me the most. However, if you know something that you think would add to the topic, feel free to share your knowledge (the more the better).
The core question was the following: Isn't this inefficient if you have dozens or hundreds of events to listen for?
And the truth is, if that was the case, it would be really inefficient. That is why it doesn't work that way.
The program (in the case of Java), or browser (in the case of Javascript), receives events from the operating system every time something happens — when the mouse is moved, when a key is pressed, when the window is resized, when a timer event expires, and so on. For each of those events, the browser needs to figure out if an event handler needs to be dispatched. For example, on a mouse left button down event, it needs to take the coordinates of the mouse and figure out what elements are underneath it, and then check if there are any event listeners registered for those events, and if so add them to the event queue to be executed the next time the engine becomes free.
Once again, feel free to add information, or correct me if you think there is something wrong or somehow inaccurate.
There's very little difference between running an event handler from onclick and from addEventListener. In both cases, it simply attaches the handler to the DOM element in question. The only significant difference between them is that you can only have one onclick attribute, but every time you call addEventListener() it adds to the list of listeners on that element -- internally there's an array of listeners that addEventListener() pushes onto.
But the way these event handlers are processed is essentially the same. When a click event is sent to an element, the browser looks up its onclick attribute and list of click listeners, and executes all of them. There's no difference in efficiency between them. The only infinite loop is the browser's main event loop, which is processing all events that are received from the OS, finding the appropriate DOM elements, seeing if they have handlers for that event, and calling the handlers.
As what others have said, internally there is no difference between the two. But using the addEventListener() method you can easily attach multiple functions on a single event rather than going through concatenations when you have lots of scripts.
with addEventListener()
Script 1
myEle.addEventLister('click', myFunc);
Script 2
myEle.addEventLister('click', myFunc2);
You see how easy it is to attach functions on an element's event.
using setAttribute()
Script 1
myEle.setAttribute('onclick', myFunc);
Script 2
myEle.setAttribute('onclick', myEle.getAttribute('onclick') + myFunc2);
The extra code is a bit of a hassle
For practical purposes, there is no difference between the 'onclick' and the 'EventListener' attributes. All in all, that's just what they are, attributes that you add or remove from a specific object. As a consequences, since they are attributes, not mere methods, they do not loop themselves, but instead serve as parameters for the "general event loop" that constantly occur in your window. Hence the lack of difference in efficiency.
However, if you have a ton of event listeners, or onclick attributes on a ton of different objects, it may reduce the overall execution speed, as the general loop has to go through more elements to check, for a specific occurred event, if there is anything listening to it; but this happens indistinctelly of how you address your events (with a listener, onclick attributes, etc.)
So, I will conclude by saying that there is no practical difference in the way these event handlers are processed. When a particular event is sent to an element, the browser looks up on its attributes and/or list of listeners related to that particular event, and executes each one of them. There's no difference in efficiency between them. The only infinite loop is the "general window loop" or the main event loop, which is processes all the events that happen, and looks for the appropriate object to check for any handlers related to that event, and should any be found, it calls the function attached to them.

Are JavaScript events always executed even if there is no one listening?

Are events in JavaScript always fired even if there are no listeners attached?
Lets say "mousemove", I move the mouse but there are no listeners in the whole app, will the browser still construct a new Event and fire it, or will it optimize and consider the fact that if there are no event listeners, just ignore the data.
I assume that each browser works differently and I'm assuming they use patterns like observer and what not, but is there a spec around that states how it should be?
Feel free to downvote this if you feel this is not correct but from my understanding and according to the DOM Level 2 Events Spec there is a sense that events are always constructed and executed but listeners need to be there, of course, to actually register them.
The reason I say "there is a sense that events are always constructed and executed" is because the Spec mentions that
This method allows the registration of event listeners on the event
target. If an EventListener is added to an EventTarget while it is
processing an event, it will not be triggered by the current actions
but may be triggered during a later stage of event flow, such as the
bubbling phase. If multiple identical EventListeners are registered on
the same EventTarget with the same parameters the duplicate instances
are discarded. They do not cause the EventListener to be called twice
and since they are discarded they do not need to be removed with the
removeEventListener method.
So if event listeners are dynamically added, there needs to be a way for the the page to know to register and listen to them. How each browser handles this is probably different as #JAAulde mentioned above but I do not think browsers would optimize for the fact that an event listener exists or not or at least nothing drastic.

Is there a reason to removeEventListener DOMContentLoaded after the event has been handled?

Like many others I use:
document.addEventListener('DOMContentLoaded',domLoadedFunc,!1);
In combination with window.onload to handle events that should fire as soon as the DOM has been loaded and parsed.
I was wondering if there is a reason to explicitly remove the DOMContentLoaded listener once it has fired.
Something along the lines of (inside our domLoadedFunc):
if(document.removeEventListener){
document.removeEventListener('DOMContentLoaded',domLoadedFunc,!1);
}
Is there a reason to remove the DOMContentLoaded listener once it has fired?
Once the event has fired, it will not fire again. So, your code will not have any different outcome if you remove it or not once it has fired the first time.
Technically, if you had a lot of event handlers all attached to the document object, it might be ever so slightly faster to remove event handlers that are no longer needed, but that is balanced with the extra code you write and execute just to remove it.
Personally, I code with thoughts in this sequence of priorities: correctness, reliability, readability, maintainability, simplicity and then performance and only do anything purely for performance sake when it's actually needed. So, following that hierarchy, I wouldn't remove the event handler because doing so is not needed for any of the first four priorities, doesn't help the simplicity of the code and isn't a performance issue that matters.
The one reason I have seen for removing an event handler like this is if you have multiple different events you are monitoring and once the first one is triggered, you want to make sure that you don't respond to any of the other events you're also monitoring. If you then remove the other handlers, then you don't have to keep a separate flag to keep track of the fact that you've already done your work (for example, if you were listening for both DOMContentLoaded and window.onload and just wanted to respond to whichever one happened first.
FYI, if you're interested in a plain javascript version of jQuery's $(document).ready() which works in all browsers (uses DOMContentLoaded when available, falls back to other means when not) which it sounds like you might be working on, there's a nice simple to use implementation of a function called docReady() here: pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it that you can either use or copy/learn concepts from.

How can I make a jQuery "ready" event handler fire after all the other ones?

I am working on a Greasemonkey script that will actually upgrade the version of jQuery used on the page. To do this, I need to add a "ready" event handler that will fire after all the other ones that might be on the page.
I know that jQuery waits for the DOM to be manipulable before invoking the ready event handlers, so is there a way to influence the order in which it executes them? Thank you,
They are called in the order they are registered. So from the top of the page to the bottom. If you need this to be the last registered ready callback register it at the very end of the body tag. Also use the $(window).load as opposed to $(document).ready.
The ready handlers are added to a readyList Array, which I'm pretty sure is private, so I don't think you'll be able to influence it directly.
One thing you could perhaps do is add your code to the readyList, but place it in a setTimeout() so it waits a bit to execute. Hopefully all the others will be done first.
Still, you may have troubles when upgrading jQuery like this. For example, there may be differences in the implementation of jQuery.cache which stores event handlers, and other data.
So if jQuery.cache was populated with one version, it may not be compatible with another.
How to control the order of functions being called in jQuery $(document).ready
According to answers given to the question above, they should fire in the order they are added (the ajax-calls in that specific question add more mud to the water than in your question).

Categories