Context:
- HTML with a long table with many rows and many columns.
- Each cell contains additional elements and sub-elements.
- In the last cell on every row, different buttons but same for each row
Question:
In this setup, resourcewise for the browser (fluidity, loading time, responsiveness,...) it it best to :
- Use a single delegate click handler on the
<table>
element ? This would be triggered by any click on any other cell or sub-element and basically triggered many more times for just nothing. - Use an event handler on every
<button>
on every row ? This would add many handlers but each would run only once when needed. - An alternative ?
Is there a real difference for the browser itself ? (lets not consider coding practices)
In the (1) delegate case, doesn't the browser have to somewhat add listeners to every child element to know it has been clicked ?
CodePudding user response:
The principal performance advantages of event delegation in the case you describe are
You only have to hook up a handler once, rather than looping through all the rows to do it. But if you have a table so big that hooking up the handlers to the buttons is a slow operation, you're likely to have other performance issues with that table.
A minor memory savings (the event registrations).
There isn't a performance disadvantage to worry about if it's a click
handler. (That might not be true of, say, a mousemove
handler.)
There are code complication and maintenance issues to consider (delegated handler is slightly more complicated to write; hooking up the handler to each button is easier to get wrong if buttons are added dynamically at some point), but you've said you're principally concerned about performance.
In the (1) delegate case, doesn't the browser have to somewhat add listeners to every child element to know it has been clicked ?
No, just the one event listener. What happens is that clicks bubble. Here's a diagram from the old
The handler is only attached to the one element. It's found when the click bubbles (propagates) to that element.
- Use a single delegate click handler on the
<table>
element ? This would be triggered by any click on any other cell or sub-element and basically triggered many more times for just nothing.
That's true, but it's harmless. The amount of work required is virtually nil.
- Use an event handler on every
<button>
on every row ? This would add many handlers but each would run only once when needed.
You don't need many handlers, you can reuse the same function for multiple buttons. It's just multiple registrations of handlers:
function buttonHandler(event) {
// ...
}
// ...
for (const btn of document.querySelectorAll(".selector-for-button")) {
btn.addEventListener("click", buttonHandler); // Adds a registration, not
// an additional function
}
That doesn't create a new function for each button, it reuses the same function for all of the buttons. During the call, event.currentTarget
will refer to the specific button that was clicked (the one we hooked up the handler to). (If the button has child elements, event.target
may refer to one of those children, but event.currentTarget
will refer to the button.)
So in any given situation, you have to weigh those various considerations to decide what you want to do.