DEV Community

Cover image for How to detect unnecessary renderings of DOM elements in your web app to improve performance
Maxime
Maxime

Posted on • Updated on

How to detect unnecessary renderings of DOM elements in your web app to improve performance

The code examples I'm giving is using Angular but it's only a very low amount of code to illustrate the main issue and that issue can happen in any Javascript application that interacts with the DOM.

Intro

Unnecessary repaints in a web app can have a critical impact on performance.

While you may be developing it on a high end device, you may not even notice. But a user running it on a lower end device may definitely.

One question remains: How to be aware of unnecessary repaints?

Illustrate the main issue

Before we dig into this, let me illustrate the original issue.

Here's a very basic app that simulates the fetching of a users array and display each of them, line by line, in a list.

Fetching users list, nothing too fancy

What happens if you click on the "Fetch people" button several times? Apprently nothing. Our list is still the same, nothing is removed, added... And yet...

Finding unnecessary repaints

When we click on the button to fetch people, in this example we emulate a network call'd return an array of people. It'd just happen to be the same result. But behind the scenes, we'd receive a brand new reference for the array... And all the objects in it! Therefore Angular assumes it has to repaint the whole list.

But how to detect this in our entire app? Do we have to be mentally aware of everything that could trigger our framework to repaint unnecessary bits of the app?

There's a very straightforward way to find out, you just have to be aware of a feature in the chrome devtool that is a little bit hidden: Paint flashing.

It can be found in: Dev tools > Hamburger menu > More tools > Rendering > Paint flashing.

Here's where to find it and a demo of what happens with this feature on:

Fetching the users list triger a repaint for the whole list

Notice how whenever we fetch the users list, the whole list flashes green? It's the dev tools showing us which DOM elements have been repainted. And if we've got the same list, surely it shouldn't repaint!

Fixing the issue

This will need some investigation and there's unfortunately no silver bullet I can give you here. In this particular case, we can tell Angular to track items by a unique ID to it's aware whether it can reuse an element or not. This blog post isn't about Angular so I won't dwell on the fix but if we use a trackBy on our ngFor like this *ngFor="let person of people; trackBy: trackById" and define the trackById function as

public trackById(_: number, person: Person) {
  return person.id;
}
Enter fullscreen mode Exit fullscreen mode

Then Angular will be able to optimize the rendering.

Fetching the users list does not triger a repaint for the whole list

Notice here that the first time we fetch the list, of course it has to be rendered once. So it flashes green. But whenever I try to fetch it again, only the button flashes (as I'm clicking onto it and it animates).

From there, we know we've optimized our app to avoid unnecessary renderings ✅.

Conclusion

This method will help you find out items that are repainted while they shouldn't, in no time. Of course, the illustration I've made isn't problematic because it's a demo app, but in real life you render hundreds or thousands of DOM elements at an intense pace to reflect fast changes in the data, it could become problematic.

I hope you enjoyed this article. If you're interested in more tips about Angular, RxJS, open source, self hosting, data privacy, and others, feel free to hit the follow button for more. Thanks for reading!

Found a typo?

If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to https://github.com/maxime1992/my-dev.to and open a new pull request with your changes. If you're interested how I manage my dev.to posts through git and CI, read more here.

Follow me

           
Dev Github Twitter Reddit Linkedin Stackoverflow

You may also enjoy reading

Top comments (8)

Collapse
 
amauryperalta28 profile image
Amaury R. Peralta Febles

Excellent, I learn something new today.

Collapse
 
maxime1992 profile image
Maxime

Glad to hear! Thanks for the kind words

Collapse
 
seandinan profile image
Sean Dinan

Didn't know about activating paint flashing before. Thanks for the tip! :)

Collapse
 
pablets profile image
Pablets

Thank you for the info! Its really important to be aware of performance. This helps a lot, thanks for sharing

Collapse
 
chideracode profile image
Chidera Humphrey

Great article.

Thank you for sharing with us.

Collapse
 
efpage profile image
Eckehard

At least the Chrome dev-tool have an option to simulate a slow device. This can also help to find perfomance issues.

Done right a Virtual DOM should prevent any unnecessary rerendering, but there are situations where this does not help. Assume you are watiting for a slow fetch, it is desireable to prevent rerendering of a screen element until the fetch is finished. Is there any way to prevent screen upday programmatically? Or even stop the DOM from displaying new content?

Collapse
 
maheshmuttinti profile image
Mahesh Muttinti

Can anybody know how to make my portfolio url like this type of preview when I share it in WhatsApp or discord?

Image description

Collapse
 
maxime1992 profile image
Maxime