[sgmb id=3]
Hey folks,
Till now we talked about increasing performance by dynamic loading and handling scope intelligently. If you missed them read about them, links mentioned at the bottom.
In this article we are going to talk about DOM and how to handle DOM to make most out of it and optimize to increase JS performance. Simply how to handle Handling DOM to increase performance and optimization.
DOM stands for Document Object Model. It is language independent API for working with HTML and XML.
Even though the DOM is a language-independent API, in the browser the interface is implemented in JavaScript. Since most of the work in client-side scripting has to do with the underlying document, DOM is an important part of everyday JavaScript coding.
Suggested Books:DOM and Javascript are two independent functionalities, thus to access one via the other costs the performance. It is very smartly defined as a toll bridge which connects Javascript and DOM. Every time you cross the bridge you have to pay the toll and that toll is performance cost (see John Hrvatin, Microsoft, MIX09, http://videos.visitmix.com/MIX09/T53F).
So what is the solution, the solution is simple just cross the bridge as less as possible. Means use or manipulate the DOM as less as possible.
Simply accessing the DOM comes at a price and making modification in the DOM is more costly as it makes the browser to make changes in page.
Lets take Example
function change(){ for(i=0;i<1000;i++){ document.getElementById('tochange').innerHTML+="hey"; } }
The problem with this code is it access the DOM twice in each iteration. Once to read the value from innerHTML
and next to make changes to it. This is very costly method to do this. A more efficient method is written below.
function newChange(){ var text=''; for(i=0;i<1000;i++){ text+='hey' } document.getElementById('tochange').innerHTML+=text; }
This function will drastically improve the performance almost around 25 to 100 times faster in different browsers. This clearly indicates how costly it is to access and write to DOM.
innerHTML vs DOM Methods
Which one to use innerHTML or DOM’s createElement Method. The discussion is going on from forever. But what about the performance. innerHTML
is more performant that document.createElement
but this difference is decreasing with the new browsers. So if you have to build very performance specific app then use innerHTML
or you can use anyone in day to day normal apps.
Cloning Node
Another way of updating page contents using DOM methods is to clone existing DOM elements instead of creating new ones—in other words, using element.cloneNode()
(where element is an existing node) instead of document.createElement()
. Cloning node is most efficient among the discussed ones.
How to increase performance while using HTML collections.
Html collections are the array like objects that holds DOM element references, these are like this
document.getElementsByName()
– contains elements by name.
document.getElementsByClassName()
– contains elements by class name.
document.getElementsByTagName()
– contains elements by tag name.
The HTML collections are in fact queries against the document, and these queries are being reexecuted every time you need up-to-date information, such as the number of elements in the collection (i.e., the collection’s length). This could be a source of inefficiencies. This is demonstrated below, lets say you have to console all the elements with class name.
var eles=document.getElementByClassName('abc'); for(i =0; i < eles.length;i++){ console.log(eles[i]); }
Now how many times this will query the DOM. It will query DOM in every loop for the length plus one for the first time. So it is quite heavy when it comes to performance. The more performant will be like this one
var eles=document.getElementByClassName('abc'); var length_eles=eles.length;
for(i =0; i <length_eles;i++){ console.log(eles[i]); }
The second one is 10 to 200 times faster in different faster. Thus always use the calculation of length and don’t calculate it again and again.
Look at the below example taken from book High performance Javascript By Nicholas C. Zakas
// slow function collectionGlobal() { var coll = document.getElementsByTagName('div'), len = coll.length, name = ''; for (var count = 0; count < len; count++) { name = document.getElementsByTagName('div')[count].nodeName; name = document.getElementsByTagName('div')[count].nodeType; name = document.getElementsByTagName('div')[count].tagName; } return name; }; // faster function collectionLocal() { var coll = document.getElementsByTagName('div'), len = coll.length, name = ''; for (var count = 0; count < len; count++) { name = coll[count].nodeName; name = coll[count].nodeType; name = coll[count].tagName; } return name; }; //fastest
function collectionNodesLocal() { var coll = document.getElementsByTagName('div'), len = coll.length, name = '', el = null; for (var count = 0; count < len; count++) { el = coll[count]; name = el.nodeName; name = el.nodeType; name = el.tagName; } return name; };
In first one, the DOM elements are accessed in every loop three times.
In the second one they call in only once but kept in outer scope.
In Third the elements are accessed from first chain of scope which made the access quite fast.
Conclusion
Minimize DOM access, and try to work as much as possible in JavaScript.
Use local variables to store DOM references you’ll access repeatedly.
Be careful when dealing with HTML collections because they represent the live, underlying document. Cache the collection length into a variable and use it when iterating, and make a copy of the collection into an array for heavy work on collections.
Read more about Javascript performance here
https://www.learnsteps.com/javascript-increasing-performance-by-handling-scopes-smartly/
https://www.learnsteps.com/javascript-increasing-performance-using-dynamic-loading/
https://www.learnsteps.com/javascript-difference-between-strict-and-lenient-equality/
Subscribe to stay updated for more such articles