Improving Web Performance with Event Delegation

Lakshay Batra
affinityanswers-tech
4 min readJun 29, 2022

I am working on the Front End of the product Affinity Ontrack, an enterprise application that combines social and location data to provide strategic insights to brands.

This web application has a list of items that shows headlines for the same. To know descriptive details for the item user has to click over that tile which expands and shows the user extra details for the item. If the expanded tile is clicked again it brings the tile to its original unexpanded state.

A simple quick-fix solution could have been, attaching a click event listener to every individual list item, but that will surely make the application heavy if there are several such items on the list — so not really future proof. Let me take you through the approach we adopted.

The optimized approach is to use event delegation. Having click event listener on the parent container of the list items and performing the required logic based on the target element clicked.

For every such use-case where we have multiple items in a list and these items has to perform a logic based on an event, it’s preferable to delegate the events using the above approach.

Event Delegation is a technique to handle events at a higher level in the DOM to improve web performance. It helps reduce the number of event listeners attached to the DOM elements.Handling events at a higher level in the DOM is possible because you can exploit Event Bubbling.

Event Bubbling is a way to do event propagation in HTML DOM. With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements i.e. event propagates from the target element to the outermost element.

Let’s see how it could be implemented in a web application.
Consider an application with n number of list items and click on every single list item has to execute logic. Having a click listener over every list item will make the application bulky. To improve on performance we’ll simply attach a click listener to the parent element in this example.

<html><head><title>Event Delegation</title></head><body><div class="category-container"><ul><li data-category="category1">Category 1</li><li data-category="category2">Category 2</li><li data-category="category3">Category 3</li></ul></div><script>document.querySelector(".category-container").addEventListener("click", (e) => {const category = e.target.dataset.category;if (category !== undefined) {window.location.href = `/${category}`;}});</script></body></html>

As we know an event bubbles up in the hierarchy. So, to know the target element we attached data attribute to every list item.
With the help of e.target, we get to know the target element clicked. As we have attached data attribute to the list items, it helps us identify the target list item which was clicked.

Another use case for Event Delegation is to implement a reusable behaviour pattern, which helps us write a logic to effectively implement behaviour that could be reusable inside the whole of the application.
Let’s look at an example of implementing a reusable behaviour pattern using event delegation.

<html><head><title>Event Delegation</title></head><body><form><label for="name">Name</label><input type="text" id="name" autocomplete="off" data-uppercase /><label for="pan">PAN</label><input type="text" id="pan" autocomplete="off" data-uppercase /><label for="phone">Phone no.</label><input type="tel" id="phone" autocomplete="off" /></form><script>document.querySelector("form").addEventListener("keyup", (e) => {if (e.target.dataset.uppercase !== undefined) {e.target.value = e.target.value.toUpperCase();}});</script></body></html>

In the example above we defined a logic over the keyup event of the parent container i.e form element, where we made the value of the input element as uppercase if the target element has an uppercase data attribute.
Implementing such reusable behaviour pattern helps minimise and optimize the code along with good readability.

Merits of Event Delegation

  • Handle events in an efficient manner
  • Memory efficient
  • Optimised number of lines of code
  • Better readability (and maintainability?)
  • A reusable behaviour pattern
  • Most importantly, improves web performance

Limitations

Not all the events propagate up in the hierarchy i.e. do not bubble. Events like blur, focus, mouse enter, etc do not propagate up in the hierarchy. Such events restrict us from using Event Delegation.

We have reaped the benefits of using Event Delegation in OnTrack application and I strongly recommend the approach in similar scenarios. Was there a better way to do this? Let me know in the comments to this post.

--

--