Home > Back-end >  document.addEventListener VS element.addEventListener
document.addEventListener VS element.addEventListener

Time:08-03

When I'm creating a web page, a confused happened to me, I noted that there are many elements waiting for clicking, so I want to ask: which practice is better for the performance?
adding event listener for the document then check the class or id for the element I clicked:

document.addEventListener('click', e => {
  let element = e.target.id;
  if(element === navbarBtn) /* do something */;
  if(element === goUpBtn) /* do something */;
  if(element === darkModeSwitcherBtn) /* do something */;
})

OR
adding event listener for each element I will click:

navbarBtn.addEventListener('click', () => {
  // doing something
})
goUpBtn.addEventListener('click', () => {
  // doing something
})
darkModeSwitcherBtn.addEventListener('click', () => {
  // doing something
})

CodePudding user response:

It really depends on how you define better, as it's very subjective.

One thing you definitely don't want to do, is have your function run every single time anyone clicks something on your page. That's very inefficient, and good code is efficient code.

It's also much clearer from a readability standpoint that the functionality you want to apply to, say, a button, is attached to that button. It'll be a nightmare later on if you have all your eventListeners attached to the document with a switch clause.

From a performance standpoint, meh. I'd imagine document is slightly faster, just due to the way the DOM works, with bubbling, etc., but the time saving (maybe 1ms), will instantly be used up on the element check.

Stick to using eventListeners on the element you're working with, unless you absolutely need it to be on a parent element to utilise event delegation, in which case it should be as close as possible to the element that needs delegating to.

More info, and a handy diagram can be found on the w3 site.

CodePudding user response:

You can use jsbench to benchmark your code. I’m using it since jsPerf is down.

Another option is that you can do it in your local workspace with Javascript’s console.time(<label>) and console.timeEnd(<label>).

CodePudding user response:

Another person here gave you a solution to figure out which is faster, but I'll go a different direction since I think you've misunderstood what you should actually be looking for. The latter is almost certainly better, regardless of whatever small performance gaps you can find. There's a few key reasons to this:

  • Reading the former code, I ask myself what happens when this event fires? The answer is I have no idea, there's too many things happening in the same function. To debug this event, I need to figure out which case is even failing and what triggers it. This is inefficient from the standpoint of saving developer hours spent on the solution.
  • If you use the former solution, what happens if the user clicks on something that is not navBarBtn, goUpBtn or darkModeSwitcherBtn? The answer as you might imagine is that the event fires and checks each condition, this again makes the code prone to weird interactions, especially if you add other events later. Moreover, from a performance standpoint this is bad too, since you're calling functions and checking conditions unecessarily.
  • The standard solution for this exists, and it is to add an event listener for each element you need an event for. This is a very common convention that you should conform to as much as possible, if anything just because it's what other people will expect, and how other code you will find out in the wild will function. There are certainly room to break convention when necessary, but following conventions like these will make it much easier for you to work with other people's code at a later stage.

In short, performance is a red herring in this question, and is a very clear case of premature optimization. It's not actually what you should be concerned with here since it'll have a very small impact on the overall performance, compared to the time you might lose having to debug functions that are attempting to do way too many things.

  • Related