documentFragment appendChild vs jquery append (v52)

Revision 52 of this benchmark created on


Description

Trying to reduce DOM reflow while inserting nodes.

NOTE: I've tried to keep the inner loop the same in all the test, since i want to know the impact of the last append command. I DO NOT WANT to optimize the inner loop. The jQuery wrapper is called on purpose.

The idea is to see what is the fastest way to do the bulk insertion of nodes.

jQuery seems to be using documentFragment when an array is given (http://www.bennadel.com/blog/2281-jquery-appends-multiple-elements-using-efficient-document-fragments.htm)

Still there is some diferences with pure js or inserting the document fragment directly.

Preparation HTML

<div id='wrapper'>
<div id="test-area" style="height: 75px; width: auto; overflow:scroll"></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>

Setup

var inner_loop_size = 1000

Teardown


    $('#test-area').empty();
  

Test runner

Ready to run.

Testing in
TestOps/sec
append items one by one ( BAD )
var Area = $('#test-area');
var raw_fragment = document.createDocumentFragment();
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  Area.append(p);
}
ready
jquery.append array of jquery wrapped nodes
var Area = $('#test-area');
var nodes = [];
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  nodes.push(p);
}
Area.append(nodes);
ready
jquery.append array of elements
var Area = $('#test-area');
var nodes = [];
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  nodes.push(p[0]);
}
Area.append(nodes);
ready
jquery.append documentFragment
var Area = $('#test-area');
var raw_fragment = document.createDocumentFragment();
var i = 0;
for (i; i < inner_loop_size; i++) {
  //the inner loop use jQuery to keep it the same as in the other loops.
  var p = $('<p/>');
  p.html("jquery elements");
  raw_fragment.appendChild(p[0]);
}
Area.append(raw_fragment);
ready
raw javascript
var Area = document.getElementById('test-area');
var raw_fragment = document.createDocumentFragment();
var i = 0;
for (i; i < inner_loop_size; i++) {
  //the inner loop use jQuery to keep it the same as in the other loops.
  var p = $('<p/>');
  p.html("jquery elements");
  raw_fragment.appendChild(p[0]);
}
Area.appendChild(raw_fragment);
ready
.detach
var Area = $('#test-area').detach();
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  Area.append(p);
}
$('#wrapper').append(Area);
ready
.replaceWith
var Area = $('#test-area');
var nodes = [];
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  nodes.push(p);
}
Area.replaceWith(Area.append(nodes));
ready
jquery string append from test #3
var Area = $('#test-area');
var nodes = "";
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  nodes += p[0].outerHTML;
}
Area.append(nodes);
ready
insertAdjacentHTML string
var Area = $('#test-area');
var nodes = "";
var i = 0;
for (i; i < inner_loop_size; i++) {
  var p = $('<p/>');
  p.html("jquery elements");
  nodes += p[0].outerHTML;
}
Area[0].insertAdjacentHTML('beforeend', nodes);
ready
jquery string append at once
var Area = $('#test-area');
var nodes = "";
var i = 0;
for (i; i < inner_loop_size; i++) {
  nodes += '<p>jquery elements</p>';
}
Area.append(nodes);
ready
raw javascript without jquery
var Area = document.getElementById('test-area');
var raw_fragment = document.createDocumentFragment();
var i = 0;
for (i; i < inner_loop_size; i++) {
  //the inner loop use jQuery to keep it the same as in the other loops.
  var p = document.createElement('p');
  p.appendChild(document.createTextNode('jquery elements'));
  raw_fragment.appendChild(p);
}
Area.appendChild(raw_fragment);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.