JavaScript: How to handle DOM to increase performance and optimization.

[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 

// 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


Gaurav Yadav

Gaurav is cloud infrastructure engineer and a full stack web developer and blogger. Sportsperson by heart and loves football. Scale is something he loves to work for and always keen to learn new tech. Experienced with CI/CD, distributed cloud infrastructure, build systems and lot of SRE Stuff.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.