Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should you add HTML to the DOM using innerHTML or by creating new elements one by one?

There are two methods to add HTML-code to the DOM and I don't know what is the best way to do it.

First method

The first way is the easy one, I could simply add HTML-code (with jQuery) using $('[code here]').appendTo(element); which is much like element.innerHTML = [code here];

Second method

Another way is to create all the elements one by one like:

// New div-element
var div = $('<div/>', {
              id: 'someID',
              class: 'someClassname'
          });

// New p-element that appends to the previous div-element
$('<p/>', {
    class: 'anotherClassname',
    text: 'Some textnode',
}).appendTo(div);

This method uses core functions like document.createElement and element.setAttribute.

When should I use the first method and when the second? Is method two faster than method one?

Edit - Result of speed tests

I did three speed tests from which the code follows:

$(document).ready(function(){
    // jQuery method - Above mentioned as the second method
    $('#test_one').click(function(){
        startTimer();
        var inhere = $('#inhere');
        for(i=0; i<1000; i++){
            $(inhere).append($('<p/>', {'class': 'anotherClassname' + i, text: 'number' + i}));
        }
        endTimer();
        return false;
    });

    // I thought this was much like the jQuery method, but it was not, as mentioned in the comments
    $('#test_two').click(function(){
        startTimer();
        var inhere = document.getElementById('inhere');
        for(i=0; i<1000; i++){
            var el = document.createElement('p')
            el.setAttribute('class', 'anotherClassname' + i);
            el.appendChild(document.createTextNode('number' + i));
            inhere.appendChild(el);
        }
        endTimer();
        return false;
    });

    // This is the innerHTML method
    $('#test_three').click(function(){
        startTimer();
        var inhere = document.getElementById('inhere'), el;
        for(i=0; i<1000; i++){
            el += '<p class="anotherClassname' + i + '">number' + i + '</p>';
        }                
        inhere.innerHTML = el;
        endTimer();
        return false;
    });
});

Which gave the following really surprising results

               Test One   Test Two   Test Three  
+-------------+---------+----------+------------+
| Chrome    5 | ~125ms  |  ~10ms   |   ~15ms    |
| Firefox 3.6 | ~365ms  |  ~35ms   |   ~23ms    |
| IE        8 | ~828ms  |  ~125ms  |   ~15ms    |
+-------------+---------+----------+------------+

All in all the innerHTML method seems to be the fastest one and is in many cases the most readable one.

like image 698
Harmen Avatar asked Feb 23 '10 15:02

Harmen


People also ask

Why should you create DOM elements instead of using innerHTML?

#1) createElement is more performant Therefore, it is less efficient than creating a new element and appending to the div. In other words, creating a new element and appending it to the DOM tree provides better performance than the innerHTML .

Can I add HTML as innerHTML?

To append using the innerHTML attribute, first select the element (div) where you want to append the code. Then, add the code enclosed as strings using the += operator on innerHTML.

Why innerHTML should not be used?

The use of innerHTML creates a potential security risk for your website. Malicious users can use cross-site scripting (XSS) to add malicious client-side scripts that steal private user information stored in session cookies.

When should I use innerHTML?

Use innerHTML when you're setting text inside of an HTML tag like an anchor tag, paragraph tag, span, div, or textarea. Use appendChild() If you're trying to add new DOM elements inside of another DOM element.


2 Answers

I point to an outdated article for purposes of people testing this for themselves. The DOM methods actually beat out the innerHTML on all of my machines so that is what I prefer. However, at the time of the article innerHTML was faster on avg. Currently the difference can only be seen in huge datasets drastically.

like image 163
bmeck Avatar answered Oct 26 '22 20:10

bmeck


Actually, neither methods use innerHTML, in both cases jQuery converts the HTML to DOM nodes. From jquery-1.3.2.js:

// If a single string is passed in and it's a single tag
// just do a createElement and skip the rest
if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
    var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
    if ( match )
        return [ context.createElement( match[1] ) ];
}

// ... some more code (shortened so nobody falls asleep) ...

// Convert html string into DOM nodes
if ( typeof elem === "string" ) {
    // Fix "XHTML"-style tags in all browsers
    elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
        return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
            all :
            front + "></" + tag + ">";
    });
    // etc...
}

Generally speaking, using innerHTML is slower than manipulating the DOM, because it invokes the HTML parser (which will parse the HTML into the DOM anyway).

like image 29
Andy E Avatar answered Oct 26 '22 19:10

Andy E