Joel Park
Joel Park

Reputation: 29

Can I make more efficient code in javascript?

for (var i = 0; i < 1000; i += 1) {
    var el = document.createElement('div');
    el.appendChild(document.createTextNode('Node ' + (i + 1)));
    document.getElementById('nodeHolder').appendChild(el);
}

The Javascript code is like this using pure syntax, is anyone make a more efficient logic please?

Upvotes: 1

Views: 133

Answers (5)

kennebec
kennebec

Reputation: 104760

You can clone an original div with its text node, so the text can be updated with a digit instead of being created and appended each iteration.

<!doctype html>
<html lang="en">
<head>
<meta charset= "utf-8">
<title>Small Page</title>
</head>
<body>
<h1>Spawning divs</h1>
<script>

var el, i=0,
pa=document.createDocumentFragment(),     
div= document.createElement('div');
div.appendChild(document.createTextNode('Node '));


while(i<1000){
    var el = div.cloneNode(true);
    el.firstChild.data+=' '+(++i);
    pa.appendChild(el);
}
document.body.appendChild(pa);
</script>
</body>
</html>

Upvotes: 0

user2728841
user2728841

Reputation: 1427

EDIT:

Edited to add divs.

Its generally quicker to build a string, and then append it to your document in one go. That way you are only touching the DOM once.

var html = "";
for (var i = 0; i < 1000; i++) {
    html += "<div>Node " + (i + 1) + "</div>";
}
document.getElementById('nodeHolder').innerHTML = html;

Updated Fiddle Here : http://jsfiddle.net/paull3876/cGAhq/

EDIT2:

As per comments I did some performance testing on the fragment answer vs this answer.

The fragment answer was substantially faster in Firefox and Chrome. The string answer here was slightly faster in Internet Explorer (10). I only tested from one machine, it may be different for older slower machines and different browser versions.

Performance test here: http://jsfiddle.net/paull3876/596cq/1/

Upvotes: 1

Butt4cak3
Butt4cak3

Reputation: 2429

If you really want to get every single piece of performance out of your code, you should only use document.getElementById once and modify the document once. Also, Node.prototype.cloneNode seems to be a bit faster than Document.prototype.createElement.

var nodeHolder = document.getElementById("nodeHolder"),
    fragment = document.createDocumentFragment(), // Create a fragment to avoid repetitive manipulation of the document
    templateNode = document.createElement("div"), // Create a template div
    el,
    i;

for (i = 1; i < 1001; i += 1) {
    // Clone the node instead of using createElement
    el = templateNode.cloneNode();
    el.appendChild(document.createTextNode("Node " + i));
    // Append to the fragment
    fragment.appendChild(el);
}

// Append the fragment to the holder
nodeHolder.appendChild(fragment);

If I missed something, feel free to tell me.

Edits:

"Shift the start and end value of i by 1 to eliminate the (i + 1)" – Xotic750

Upvotes: 1

Amine Hajyoussef
Amine Hajyoussef

Reputation: 4430

you're triggering a browser reflow on every iteration, which decreases heavily the performance , you should instead do:

var docFragment = document.createDocumentFragment(); // creates empty fragment
for (var i = 1; i <= 1000; ++i) {
    var el = document.createElement('div');
    el.innerHTML = 'Node ' + i;
    docFragment.appendChild(el);
}
document.getElementById('nodeHolder').appendChild(docFragment);

this way you're modifying the dom only once.
Try to measure the execution time and you'll see a huge difference.
Here's an interesting article about optimizing Javascript Dom manipulation.

Upvotes: 4

Okan Kocyigit
Okan Kocyigit

Reputation: 13421

You should get nodeHolder only one time, document.getElementById in every loop is unnecessary

var nodeHolder = document.getElementById('nodeHolder')
for (var i = 0; i < 1000; i += 1) {
    var el = document.createElement('div');
    el.innerHTML = 'Node ' + (i + 1);
    nodeHolder.appendChild(el);
}

Upvotes: 1

Related Questions