jQuery $( '.class' ) vs getElementsByClassName( 'class' )

JavaScript performance comparison

Revision 3 of this test case created by Marcin

Preparation code

<div class="class1" id="id1">
</div>
<div class="class2" id="id2">
</div>
<div class="class3" id="id3">
</div>
<div class="class4" id="id4">
</div>
<div class="class5" id="id5">
</div>
<div class="class6" id="id6">
</div>
<div class="class7" id="id7">
</div>
<div class="class8" id="id8">
</div>
<div class="class9" id="id9">
</div>
<div class="class10" id="id10">
</div>
<div class="class11" id="id11">
</div>
<div class="class12" id="id12">
</div>
<div class="class13" id="id13">
</div>
<div class="class14" id="id14">
</div>
<div class="class15" id="id15">
</div>
<div class="class16" id="id16">
</div>
<div class="class17" id="id17">
</div>
<div class="class18" id="id18">
</div>
<div class="class19" id="id19">
</div>
<div class="class20" id="id20">
</div>
<div class="class21" id="id21">
</div>
<div class="class22" id="id22">
</div>
<div class="class23" id="id23">
</div>
<div class="class24" id="id24">
</div>
<div class="class25" id="id25">
</div>
<div class="class26" id="id26">
</div>
<div class="class27" id="id27">
</div>
<div class="class28" id="id28">
</div>
<div class="class29" id="id29">
</div>
<div class="class30" id="id30">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js">
</script>
      
<script>
Benchmark.prototype.setup = function() {
  function myGetElementsByClassName(className) {
    var results = [];
  
    var traverse = function(node, func) {
        if (node.nodeType == 1) {
          func(node);
        }
        node = node.firstChild;
        while (node) {
          traverse(node, func);
          node = node.nextSibling;
        }
        }
        
        
        
        
        
        
        
        
        
        
        
    traverse(document.body, function(node) {
      var a, c = node.className,
          i;
      if (c) {
        a = c.split(' ');
        for (i = 0; i < a.length; i++) {
          if (a[i] === className) {
            results.push(node);
            break;
          }
        }
      }
    });
    return results;
  }
  
  function walkTheDOM(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
      walkTheDOM(node, func);
      node = node.nextSibling;
    }
  }
  
  function dougGetElementsByClassName(className) {
    var results = [];
    walkTheDOM(document.body, function(node) {
      var a, c = node.className,
          i;
      if (c) {
        a = c.split(' ');
        for (i = 0; i < a.length; i++) {
          if (a[i] === className) {
            results.push(node);
            break;
          }
        }
      }
    });
    return results;
  }
  
  /*
  	Developed by Robert Nyman, http://www.robertnyman.com
  	Code/licensing: http://code.google.com/p/getelementsbyclassname/
  */
  var ultimateGetElementsByClassName = function(className, tag, elm) {
      if (document.getElementsByClassName) {
        return elm.getElementsByClassName(className);
      } else if (document.evaluate) {
        getElementsByClassName = function(className, tag, elm) {
          tag = tag || "*";
          elm = elm || document;
          var classes = className.split(" "),
              classesToCheck = "",
              xhtmlNamespace = "http://www.w3.org/1999/xhtml",
              namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace) ? xhtmlNamespace : null,
              returnElements = [],
              elements, node;
          for (var j = 0, jl = classes.length; j < jl; j += 1) {
            classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
          }
          try {
            elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
          } catch (e) {
            elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
          }
          while ((node = elements.iterateNext())) {
            returnElements.push(node);
          }
          return returnElements;
        };
      } else {
        getElementsByClassName = function(className, tag, elm) {
          tag = tag || "*";
          elm = elm || document;
          var classes = className.split(" "),
              classesToCheck = [],
              elements = (tag === "*" && elm.all) ? elm.all : elm.getElementsByTagName(tag),
              current, returnElements = [],
              match;
          for (var k = 0, kl = classes.length; k < kl; k += 1) {
            classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
          }
          for (var l = 0, ll = elements.length; l < ll; l += 1) {
            current = elements[l];
            match = false;
            for (var m = 0, ml = classesToCheck.length; m < ml; m += 1) {
              match = classesToCheck[m].test(current.className);
              if (!match) {
                break;
              }
            }
            if (match) {
              returnElements.push(current);
            }
          }
          return returnElements;
        };
      }
      return getElementsByClassName(className, tag, elm);
      };

};
</script>

Preparation code output

<div class="class1" id="id1"> </div> <div class="class2" id="id2"> </div> <div class="class3" id="id3"> </div> <div class="class4" id="id4"> </div> <div class="class5" id="id5"> </div> <div class="class6" id="id6"> </div> <div class="class7" id="id7"> </div> <div class="class8" id="id8"> </div> <div class="class9" id="id9"> </div> <div class="class10" id="id10"> </div> <div class="class11" id="id11"> </div> <div class="class12" id="id12"> </div> <div class="class13" id="id13"> </div> <div class="class14" id="id14"> </div> <div class="class15" id="id15"> </div> <div class="class16" id="id16"> </div> <div class="class17" id="id17"> </div> <div class="class18" id="id18"> </div> <div class="class19" id="id19"> </div> <div class="class20" id="id20"> </div> <div class="class21" id="id21"> </div> <div class="class22" id="id22"> </div> <div class="class23" id="id23"> </div> <div class="class24" id="id24"> </div> <div class="class25" id="id25"> </div> <div class="class26" id="id26"> </div> <div class="class27" id="id27"> </div> <div class="class28" id="id28"> </div> <div class="class29" id="id29"> </div> <div class="class30" id="id30"> </div>

Test runner

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

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
$('.class')
for (var i = 1; i <= 30; i++) {

  var x = $('.class' + i);

};
pending…
getElementsByClassName('class')
for (var i = 1; i <= 30; i++) {

  var x = document.getElementsByClassName('class' + i);

};
pending…
myGetElementsByClassName
for (var i = 1; i <= 30; i++) {

  var x = myGetElementsByClassName('class' + i);

};
pending…
dougGetElementsByClassName
for (var i = 1; i <= 30; i++) {

  var x = dougGetElementsByClassName('class' + i);

};
pending…
ultimateGetElementsByClassName
for (var i = 1; i <= 30; i++) {

  var x = ultimateGetElementsByClassName('class' + i);

};
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.

0 Comments