.append VS .html VS .innerHTML performance

All three are slow to me. Modifying the dom on each iteration is slow.

http://jsperf.com/jquery-append-vs-html-list-performance/24

I just added a new test in there:

var html = [];
for (var i = 0; i < len; i++) {
  html.push('<div>Test ' + i + '</div>');
}

document.getElementById('list').innerHTML = html.join('');

This is much faster again. :)

My method in Firefox does 26k Ops/sec vs 1,000, 10,000, and 13

enter image description here


That benchmark is worthless. innerHTML is always faster than DOM manipulation.

jQuery seems faster because it prepares a string with all the HTML first while the others do one operation each iteration. Also note that jQuery.html() uses innerHTML whenever it can.

jQuery from benchmark

var html = '';
for (var i = 0; i < len; i++) {
  html += '<div>Test ' + i + '</div>';
}

$('#list').html(html);

innerHTML from benchmark

var list = document.getElementById('list');
for (var i = 0; i < len; i++) {
  list.innerHTML = list.innerHTML + '<div>Test ' + i + '</div>';
}

The test for innerHTML would be a lot faster if it was written like:

var list = document.getElementById('list');
var html = '';

for (var i = 0; i < len; i++) {
    html += '<div>Test ' + i + '</div>';
}

list.innerHTML = html;

http://jsben.ch/#/yDvKH


How can .html be faster than .innerHTML when the .html is using .innerHTML with a lot of extra code? Here .html implementation in jQuery (taken directly from jQuery file).

html: function( value ) {
    return jQuery.access( this, function( value ) {
        var elem = this[0] || {},
            i = 0,
            l = this.length;

        if ( value === undefined ) {
            return elem.nodeType === 1 ?
                elem.innerHTML.replace( rinlinejQuery, "" ) :
                undefined;
        }

        // See if we can take a shortcut and just use innerHTML
        if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
            ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
            ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
            !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {

            value = value.replace( rxhtmlTag, "<$1></$2>" );

            try {
                for (; i < l; i++ ) {
                    // Remove element nodes and prevent memory leaks
                    elem = this[i] || {};
                    if ( elem.nodeType === 1 ) {
                        jQuery.cleanData( getAll( elem, false ) );
                        elem.innerHTML = value;
                    }
                }

                elem = 0;

            // If using innerHTML throws an exception, use the fallback method
            } catch(e) {}
        }

        if ( elem ) {
            this.empty().append( value );
        }
    }, null, value, arguments.length );
}