When data is being delivered to web applications the chances are that you'll be displaying that data within the user interface (UI). In order to do this you need to find the element in the Document Object Model (DOM) and then update it. Whilst the performance of web browsers is improving all the time DOM manipulation can still be costly (use up time and resources) if you are pushing through a lot of data so it's worth keeping the interaction with the DOM to a minimum. You should also consider how you access the DOM. Should you use a utility/library function or should you use native browser methods?
To demonstrate this, and show the considerations I've written a few small helper functions which can be called a number of times from tests and for each test I'll time how long it takes to update the DOM a certain number of times.
For many web developers a script tag referencing in the jQuery library is one of the first elements to be added to any web page - it's even in some web framework templates by default. So, a good first test is to time how long it takes for jQuery to update an element a number of times.
Now that we've defined one way of updating the DOM let's add a way of caching a reference to the jQuery object that we create with the
jQuery(selector) call. So, instead of having to make that call each time we can just access the object from a cache. This means that a new
jQuery object doesn't need to be created for every update.
jQuery uses CSS selectors to find elements so rather than going directly to single elements using
id attributes let's also define a test that uses a nested selector:
div.top div.middle div.bottom p.update-me.
Finally, as a comparison let's define functions which update the DOM by directly using the native
document.querySelector native browser functions, and both of these again using the caching technique we used earlier.
If we execute each of these methods so that they are called 500 times to update the DOM and repeat that 10 times we see results as shown in the following graph.
And if we take each of the results and average them out we see the following:
If you'd like to try running the tests with different numbers you can do so using this form. When the tests complete the graphs will update. The numbers have been restricted in an effort to reduce the chances of your web browser hanging.
The graphs are dynamically generated based on the browser viewing this blog post so the results will differ but even so the graphs suggest to following to me:
- If you are sending a reasonable number of updates, and you are going to be updated the UI a lot, that you should be using
document.getElementByIdto access and update the DOM.
- If you want to use jQuery and the DOM structure isn't going to update all that often then the caching references to jQuery objects is an efficient mechanism.
- If you are are using CSS queries then the native
document.querySelectorperforms better than
jQuery. In both cases the complexity of the query is undoubtedly going to impact the performance.
- Caching lookups of
document.querySelectoris a good idea since it improves performance.
- Unsurprisingly direct
idattributes lookups are fastest of all.
document.getElementByIdis the fastest way of accessing the DOM and caching lookups doesn't make a big difference.
The important thing is that you will know better than anybody else the sort of data that is going to be pushed into your app and it does with it. Balance performance and maintainability within your application and make decisions about how you are going to deal with updating the DOM based on that.
If your application gets infrequent updates then you'll be fine using jQuery all the time. If your app gets a lot of realtime data streamed to it, maybe it's a trading application, then you'll need to fine-tune your app.