className VS classList Showdown (v24)

Revision 24 of this benchmark created on


Description

How much faster is classList.add/remove than className regex manipulation?

Preparation HTML

<style type="text/css">
  .blah{color: black;}
  .bleh{font-size: 300px}
  .foo{color:#F00;height:50px;opacity:0.3;} 
  .bar{color:#0F0;height:70px;opacity:0.5;font-size: 900px} 
  .baz{color:#00F;height:90px;opacity:0.7;font-weight: bold}
</style>
<div id="base" class="">
    test 1
</div>

Setup

var node = document.getElementById('base');
    
    var lastClassName = 'blah bleh';
    node.className = lastClassName;
    var classList = node.classList;
    var dynamicClasses = {foo: 1, bar: 1, baz: 1}
    var i=0;

Test runner

Ready to run.

Testing in
TestOps/sec
classList (naive)
if (i++ % 2 === 0) {
  classList.add('foo');
  classList.add('bar');
  classList.add('baz');
}

else {
  classList.remove('foo');
  classList.remove('bar');
  classList.remove('baz');

}
ready
className (optimized)
if (i++ % 2 === 0) {
  if (node.className === lastClassName) {
    lastClassName = 'blah bleh foo bar baz';
  } else {
    lastClassName = 'blah bleh foo bar baz';
  }
}

else {
  if (node.className === lastClassName) {
    lastClassName = 'blah bleh';
  } else {
    lastCassName = 'blah bleh';
  }
}

node.className = lastClassName;
ready
className + classList (hybrid)
var obj = {};
var len = classList.length;
for (var i=0; i < len; i++) {
  obj[classList[i]] = true;
}

if (i++ % 2 === 0) {
  obj['foo'] = true;
  obj['bar'] = true;
  obj['baz'] = true;
  node.className = Object.keys(obj).join(' ');
}

else {
  delete obj['foo'];
  delete obj['bar'];
  delete obj['baz'];
  node.className = Object.keys(obj).join(' ');
}
ready
move static classes to end
var obj = {};
var len = classList.length;
var externals = [];

for (var i=0; i < len; i++) {
  var cls = classList[i];
  if (!dynamicClasses.hasOwnProperty(cls)) {
    externals.push(cls);
  }
}

if (i++ % 2 === 0) {
  node.className = 'foo bar baz ' + externals.join(' ');
}

else {
  node.className = externals.join(' ');
}
ready

Revisions

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