jQuery Tip #2 - Manipulating the DOM in a Loop

Interested in learning more about jQuery? Check out the jQuery Fundamentals course at Pluralsight.com.


One of jQuery's greatest strengths is its ability to manipulate the DOM with a minimal amount of code. It's so easy to change things that we often don't think about what's happening under the covers. For example, consider the following code that appends nodes to an object named parentDiv.


var parentDiv = $('#emailList');
for (var i = 0; i < 100; i++) {
    parentDiv.append('<div>' + i + '</div>');
}

This is one of the more common ways to append nodes into a given parent. Although it works fine, it's not optimal because jQuery has to constantly perform DOM operations in the loop. You may not notice a problem when looping through 100 items, but as that number increases to a larger number the performance can start to degrade. A more efficient (yet simple) approach from a performance standpoint is shown next:


var parentDiv = $('#emailList');
var divs = '';
for (var i = 0; i < 100; i++) {
  divs += '<div>' + i + '</div>';
}
parentDiv.html(divs);

The previous code only touches the DOM once after the loop has completed resulting in better overall performance. While a lot of string concatenation is occurring, it turns out that going that route is much more efficient than calling append() multiple times.

Keep in mind that you can always manipulate the DOM directly as well and increase performance even more in some cases by using things like document.createDocumentFragment() and other techniques. While I prefer to use jQuery functions whenever possible, sometimes it's necessary to step outside of jQuery’s API for a given task and use the native DOM API instead.

A test page available at http://jsperf.com/strings-vs-array-join-vs-doc-fragment/8 shows different techniques that can be used for updating the DOM while using a loop as well as their individual performance results. An example of the test results and the different techniques tested are shown next. You’ll notice that calling jQuery’s append() function in a loop doesn’t fare too well compared to some of the other more “native” DOM options.

Test Ops/sec
Strings
var str = '';
var c = '<li>' + d.first + ' ' + d.second + '</li>'
for (var i = 0; i < 100; i++) {
  str += c;
}
document.getElementById('list').innerHTML = str;
1,226±0.84%61% slower
Array (using push)
var arr = [];
var c = '<li>' + d.first + ' ' + d.second + '</li>'
for (var i = 0; i < 100; i++) {
  arr.push(c);
}
document.getElementById('list').innerHTML = arr.join('');
1,234±0.35%61% slower
Doc Fragment
var doc = document.createDocumentFragment();
var c = d.first + ' ' + d.second;

for (var i = 0; i < 100; i++) {
  var e = document.createElement("li");
  e.textContent = c;
  doc.appendChild(e);
}
document.getElementById('list').appendChild(doc);
3,020±3.24%fastest
Array (using index)
var arr = [];
var c = '<li>' + d.first + ' ' + d.second + '</li>'
for (var i = 0; i < 100; i++) {
  arr[i] = c;
}
document.getElementById('list').innerHTML = arr.join('');
1,223±0.46%61% slower
Array join then string concat
var arr = [];
var c = d.first + ' ' + d.second;

for (var i = 0; i < 100; i++) {
  arr[i] = c;
}
document.getElementById('list').innerHTML = '<li>' + arr.join('</li><li>') + '</li>';
1,252±0.37%60% slower
DOM List
var list = document.getElementById('list');
var c = d.first + ' ' + d.second;

for (var i = 0; i < 100; i++) {
  var e = document.createElement("li");
  e.textContent = c;
  list.appendChild(e);
}
3,144±0.00%fastest
jquery
var $list = $("#list");
var c = '<li>' + d.first + ' ' + d.second + '</li>';
for (var i = 0; i < 100; i++) {
  $list.append(c);
}
428±9.06%86% slower
doc fragment 2
var doc = document.createDocumentFragment();
var c = d.first + ' ' + d.second;
var e = document.createElement("li");
e.textContent = c;
for (var i = 0; i < 100; i++) {
  doc.appendChild(e.cloneNode(true));
}
document.getElementById('list').appendChild(doc);
3,241±11.16%fastest


Conclusion

As Peter Parker’s Uncle said in Spider-Man, “With great power comes great responsibility”. The same can be said about the power jQuery provides to developers. Take time to research sections of code that you know are critical for the performance of your application. Just because you can use a particular function doesn’t mean you should. Check out http://james.padolsey.com/jquery/ if you’d like an easy way to see what jQuery functions are doing behind the scenes.

 

 

 

 

 

If you’re interested in learning more about jQuery or JavaScript check out my jQuery Fundamentals or Structuring JavaScript Code courses from Pluralsight. We also offer onsite/online training options as well at http://www.thewahlingroup.com.

Published Wednesday, February 08, 2012 10:22 PM by dwahlin
Filed under: , ,

Comments

# Dew Drop &ndash; February 9, 2012 (#1,262) | Alvin Ashcraft&#039;s Morning Dew

Pingback from  Dew Drop &ndash; February 9, 2012 (#1,262) | Alvin Ashcraft&#039;s Morning Dew

# 2012??? 2??? 10??? it ?????? ?????? |

Thursday, February 09, 2012 7:57 PM by 2012??? 2??? 10??? it ?????? ?????? |

Pingback from  2012??? 2??? 10??? it ?????? ?????? |

# Windows Dev News for February 12, 2012 - #0039

Sunday, February 12, 2012 8:56 PM by Community Blogs

[SC1215] In This Issue: Michael Washington ( -2- ), Kevin Dockx ( -2- ), Sumit Dutta , Dhananjay Kumar

# jQuery Tip #3 - Using the data() Function

Friday, February 17, 2012 2:07 AM by Dan Wahlin's WebLog

Previous Tips: jQuery Tip #1 - Defining a Context When Using Selectors jQuery Tip #2 - Manipulating the

# re: jQuery Tip #2 - Manipulating the DOM in a Loop

Sunday, February 19, 2012 4:44 AM by Dev Rex

Nice tut. very useful. thanks.

# jQuery tips &laquo; IT Tutorials

Sunday, February 26, 2012 12:09 PM by jQuery tips « IT Tutorials

Pingback from  jQuery tips &laquo; IT Tutorials

# jQuery Tip #3 – Using the on() Function

Sunday, February 26, 2012 2:24 PM by Dan Wahlin's WebLog

Previous Tips: jQuery Tip #1 - Defining a Context When Using Selectors jQuery Tip #2 - Manipulating the

# jQuery Tip #4 – Use the on() Function for Event Handling

Sunday, February 26, 2012 2:26 PM by Dan Wahlin's WebLog

Previous Tips: jQuery Tip #1 - Defining a Context When Using Selectors jQuery Tip #2 - Manipulating the

# jQuery Tip #5: Using jQuery’s end() Function to Work with Sets

Sunday, February 26, 2012 4:45 PM by Dan Wahlin's WebLog

Previous Tips: jQuery Tip #1 - Defining a Context When Using Selectors jQuery Tip #2 - Manipulating the

# jQuery Tip #5: Using jQuery???s end() Function to Work with Sets (Dan Wahlin&#8217;s WebLog) | zdima.net

Pingback from  jQuery Tip #5: Using jQuery???s end() Function to Work with Sets (Dan Wahlin&#8217;s WebLog) | zdima.net

# jQuery Tip #6 ??? Creating a Custom jQuery Selector :: Learning

Pingback from  jQuery Tip #6 ??? Creating a Custom jQuery Selector :: Learning