jQuery DOM builder vs custom DOM builder

JavaScript performance comparison

Revision 4 of this test case created by Gleb Mazovetskiy

Info

We'll insert the same thing - a bunch of rows with some cells with some info.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://glebm.github.com/DOMBrew/dombrew-1.4.3.min.js"></script>
<p>Table with no rows.</p>
<!--<p>Insert this:</p>
<tr id="row-of-one"><td class="red"><ul><li class="lists"></li><li></li></ul></td><td class="blue"><p>This is a bunch of text that is right here.</p></td><td class="orange"><table id="smallertable"><thead><tr><th colspan="2">this is small</th></tr></thead><tbody><tr><td>Go win.</td><td>Go fight.</td></tr></tbody></table></td><td class="purple"><div id="divided">Content</div></td></tr>-->
<table id="thetable" style="display:none;"></table>
<script>
  function createNode(a) {
   var c = null;
   try {
    c = createDOMElement(a)
   } catch (b) {
    sysout("Failed to create node " + a + ". " + b.message)
   }
   return c
  }
 
  function createText(a) {
   try {
    a = a.toString()
   } catch (c) {
    sysout("Error in createText: " + c.message)
   }
   return a.indexOf("<br/>") != -1 || a.indexOf("<br>") != -1 ? handleTextParas(a) : document.createTextNode(a)
  }
 
  function createTextAsInput(a) {
   try {
    a = a.toString()
   } catch (c) {
    sysout("Error in createTextAsInput: " + c.message)
   }
   return a.indexOf("<br/>") != -1 || a.indexOf("<br>") != -1 ? handleTextParasAsInput(a) : document.createTextNode(a)
  }
 
  function handleTextParas(a) {
   var c = [],
       b = [],
       d = 0;
   if (a.contains("<br/>")) {
    b = a.split("<br/>");
    a = 0;
    for (var e = b.length; a < e; a++) {
     "" != b[a] && c.push(createText(b[a]));
     d != b.length - 1 && c.push(createNode("br"));
     d++
    }
   } else if (a.contains("<br>")) {
    b = a.split("<br>");
    a = 0;
    for (e = b.length; a < e; a++) {
     "" != b[a] && c.push(createText(b[a]));
     d != b.length - 1 && c.push(createNode("br"));
     d++
    }
   }
   return c
  }
 
  function handleTextParasAsInput(a) {
   var c = [],
       b = [],
       d = 0;
   if (a.contains("<br/>")) {
    b = a.split("<br/>");
    a = 0;
    for (var e = b.length; a < e; a++) {
     "" != b[a] && c.push(createText(b[a]));
     d != b.length - 1 && c.push(createText("\n"));
     d++
    }
   } else if (a.contains("<br>")) {
    b = a.split("<br>");
    a = 0;
    for (e = b.length; a < e; a++) {
     "" != b[a] && c.push(createText(b[a]));
     d != b.length - 1 && c.push(createText("\n"));
     d++
    }
   }
   return c
  }
 
  function createElement(a, c) {
   if (null == c) {
    sysout("Invalid usage of create element method (" + a + ").");
    return null
   } else {
    for (var b = createNode(a), d = 0, e = c.length; d < e; d++) try {
     if (null != c[d][0]) for (var f = 0, g = c[d].length; f < g; f++) b.appendChild(c[d][f]);
     else throw new Exception("Not array child elements.");
    } catch (i) {
     try {
      b.appendChild(c[d])
     } catch (h) {
      sysout("Invalid usage of create element method (" + a + ").[1]")
     }
    }
    return b
   }
  }
 
  function createAttributeElement(a, c, b) {
   for (var d = createNode(a), e = 0, f = c.length; e < f; e++) {
    var g = c[e].split("=");
    if (g.length > 2) {
     for (var i = "", h = 0, j = 0, k = g.length; j < k; j++) {
      if (h != 0) {
       i += g[j];
       if (h != g.length - 1) i += "="
      }
      h++
     }
     try {
      d.setAttribute(g[0], i)
     } catch (l) {
      sysout("Array > 2, failed on node " + a + ":" + l)
     }
    } else if (g.length == 1) sysout("Invalid usage of create attribute element with children parameters (" + g[0] + ").");
    else try {
     d.setAttribute(g[0], g[1])
    } catch (m) {
     sysout("Failed:" + m)
    }
   }
   if (null != b && b.length) {
    a = 0;
    for (c = b.length; a < c; a++) try {
     d.appendChild(b[a])
    } catch (p) {
     try {
      e = 0;
      for (var n = b[a].length; e < n; e++) d.appendChild(b[a][e])
     } catch (o) {
      sysout("Error in javascript coding: " + o.message + "")
     }
    }
   }
   return d
  }
 
  function createLink(a, c) {
   for (var b = createNode("a"), d = 0, e = a.length; d < e; d++) {
    var f = a[d].split("=");
    if (f.length > 2) {
     for (var g = "", i = 0, h = 0, j = f.length; h < j; h++) {
      if (i != 0) g += i < f.length - 1 ? f[h] + "=" : f[h];
      i++
     }
     b.setAttribute(f[0], g)
    } else if (f.length == 1) sysout("Invalid usage of create link parameters (" + f[0] + ").");
    else try {
     b.setAttribute(f[0], f[1])
    } catch (k) {
     sysout(k)
    }
   }
   b.appendChild(createText(c));
   return b
  }
 
  function searchedNode(a, c, b, d, e, f) {
   if ("text" == a) return findSearchValue(c, b, d, e, f);
   else {
    c = findSearchValue(c, b, d, e, f);
    b = createNode(a);
    d = 0;
    for (e = c.length; d < e; d++) try {
     if (null != c[d][0]) {
      f = 0;
      for (var g = c[d].length; f < g; f++) b.appendChild(c[d][f])
     } else throw new Exception("Not array child elements.");
    } catch (i) {
     try {
      b.appendChild(c[d])
     } catch (h) {
      sysout("Invalid usage of searched node method (" + a + ").[2]")
     }
    }
    return b
   }
  }
 
  function createDOMElement(a) {
   return document.createElement(a)
  };
</script>
<script>
Benchmark.prototype.setup = function() {
    $('#thetable').empty()
};
</script>

Preparation code output

Table with no rows.

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
jQuery DOM inserts
var table = $('#thetable');
table.append("<tr id='row-of-one'><td class='red '><ul><li class='lists '>one</li><li>two</li></ul></td><td class='blue '><p>This is a bunch of text that is right here.</p></td><td class='orange '><table id='smallertable '><thead><tr><th colspan='2 '>this is small</th></tr></thead><tbody><tr><td>Go win.</td><td>Go fight.</td></tr></tbody></table></td><td class='purple '><div id='divided '>Content</div></td></tr>");
 
pending…
Custom DOM
var table = $('#thetable');
table[0].appendChild(createAttributeElement('tr', ['class=row-of-one'], [
createAttributeElement('td', ['class=red'], [
createElement('ul', [
createAttributeElement('li', ['class=lists'], [createText('one')]), createElement('li', [createText('two')]), ]), ]), createAttributeElement('td', ['class=blue'], [
createElement('p', [createText('This is a bunch of text that is right here.')])]), createAttributeElement('td', ['class=orange'], [
createAttributeElement('table', ['id=smallertable'], [
createElement('thead', [
createElement('tr', [
createAttributeElement('th', ['colspan=2'], [createText('this is small')])])]), createElement('tbody', [
createElement('tr', [
createElement('td', [createText('Go win.')]), createElement('td', [createText('Go fight.')])])])])]), createAttributeElement('td', ['class=purple'], [
createAttributeElement('div', ['id=divided'], [createText('Content')])])]));
pending…
DOMBrew
var $b = DOMBrew;

$("#thetable").append($b('tr#row-of-one').append(
  $b('td.red').append(
    $b('ul').append(
      $b('li.lists', 'one'),
      $b('li', 'two')
    )
  ),
  $b('td.blue').append(
    $b('p', 'This is a bunch of text that is right here.')
  ),

  $b('td.orange').append(
    $b('table#smallertable').append(
      $b('thead').append(
        $b('tr').append(
          $b('th', { colspan: 2, text: 'this is small' })
        )
      ),
      $b('tbody').append(
        $b('tr').append(
          $b('td', 'Go win.'),
          $b('td', 'Go fight.')
        )
      )
    )    
  ),

  $b('td.purple').append($b('#divided', 'Content'))
).dom());
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