innerHTML vs jQuery vs createElement() and appendChild()

JavaScript performance comparison

Revision 10 of this test case created

Info

Compares the performance of adding elements to the DOM by using strings and innerHTML, creating the DOMElement node tree and appending with appendChild(), and using jQuery to replace content with $elm.html().

Preparation code

<!-- Existing DOM elements into which the tests will append new content -->
<div id="parent-inject">
  Replace me via
  <code>
    elm.innerHTML()
  </code>
</div>
<hr/>
<div id="parent-create">
  Replace me via
  <code>
    elm.appendChild()
  </code>
</div>
<hr/>
<div id="parent-jquery">
  Replace me via
  <code>
    $elm.html()
  </code>
</div>
<hr/>
<div id="parent-iframe">
  Replace me via parsing in hidden iframe
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script>
Benchmark.prototype.setup = function() {
    /***
     * Create a realistic, level playing field by storing references to container
     * elements beforehand, as you would likely do in a real webapp.
     ***/

   
    // Existing DOM elements into which the tests will append new content
    var parentInject = document.getElementById('parent-inject');
    var parentCreate = document.getElementById('parent-create');
    var $parentJQuery = $('#parent-jquery');
    var parentIframe = document.getElementById('parent-iframe');
   
   
    // This content string is assigned to a variable in each loop of each test.
    var contentString1 = '<div class="test" onmousemove="myFunction('
    var contentString2 = ')"><h1>This is a test</h1><p>This is only a test</p></div>';
   
    // see: https://community.jboss.org/people/wesleyhales/blog/2011/08/28/fixing-ajax-on-mobile-devices
   
   
    function getFrame() {
      var frame = document.getElementById("temp-frame");
      if (!frame) {
        // create frame
        frame = document.createElement("iframe");
        frame.setAttribute("id", "temp-frame");
        frame.setAttribute("name", "temp-frame");
        frame.setAttribute("seamless", "");
        frame.setAttribute("sandbox", "");
        frame.style.display = 'none';
        document.documentElement.appendChild(frame);
      }
      return frame.contentDocument;
    }
};
</script>

Preparation code output

Replace me via elm.innerHTML()

Replace me via elm.appendChild()

Replace me via $elm.html()

Replace me via parsing in hidden iframe

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
innerHTML
// Initialize the new content string. Assigns the string to a local variable to be more realistic (e.g. you'd likely do the same with the response body of an AJAX call).
var content = contentString1 + Math.random() + contentString2;

// Inject the new content
parentInject.innerHTML = content;
pending…
createElement() and appendChild()
// Remove the old content
var childNodes = parentCreate.childNodes,
    i = 0,
    len = childNodes.length;
for (i; i < len; ++i) {
  parentCreate.removeChild(childNodes[i]);
}

// Construct the new content
var div = document.createElement('div');
div.className = 'test';
div.onmousemove = function() {
  myFunction(Math.random())
};

var h1 = document.createElement('h1');
var text = document.createTextNode('This is a test');

var p = document.createElement('p');
var text2 = document.createTextNode('This is only a test');

h1.appendChild(text);
p.appendChild(text2);
div.appendChild(h1);
div.appendChild(p);

// Insert the new content
parentCreate.appendChild(div);
pending…
jQuery.fn.html()
// Initialize the new content string. Assigns the string to a local variable to be more realistic (e.g. you'd likely do the same with the response body of an AJAX call).
var content = contentString1 + Math.random() + contentString2;

// Inject the new content
$parentJQuery.html(content);
pending…
iframe parsing
// Remove the old content
var childNodes = parentIframe.childNodes,
    i = 0,
    len = childNodes.length;
for (i; i < len; ++i) {
  parentIframe.removeChild(childNodes[i]);
}

// parse HTML string in hidden iframe
var frame = getFrame();
frame.write(contentString1 + Math.random() + contentString2);

// take resulting DOM nodes as new content
var incomingElements = frame.getElementsByClassName('*');

parentIframe.appendChild(document.adoptNode(incomingElements));
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment