.style vs .className vs .setAttribute (v4)

Revision 4 of this benchmark created by galambalazs on


Description

Is it faster to use JavaScript .style, or to change the class of an object using .className?

Edit Note: The original test case was not general enough. Hiding an element is just one side of the story, you should be able to make it visible again. Also you may want to hide an element which already has a class, you need a bit more complex logic in this case. Finally, setAttribute("class", ...) doesn't work in IE, it needs className instead.

Conclusion: Setting style directly wins in IE 6-7, Opera. No noticable difference in all other browsers.

Preparation HTML

<style type="text/css">
 .hide {
   display:none;
 }
</style>

<ul id="nav">
  <li><a href="#">elem1</a></li>
  <li><a href="#">elem2</a></li>
  <li><a href="#">elem3</a></li>
  <li><a href="#">elem4</a></li>
  <li><a href="#">elem5</a></li>
</ul>
<script>
  // IE only supports setAttribute("className")
  var ATTR_CLASS_NAME = (function() {
   var el = document.createElement("div");
   el.className = "test";
   if (el.getAttribute("class") === "test") return "class";
   else return "className";
  })();
  
  function addClass(el, className) {
   var cname = el.className;
   if (cname.indexOf(className) == -1) {
    el.className = cname + " " + className;
   }
  }
  
  function addClass2(el, className) {
   var cname = el.getAttribute(ATTR_CLASS_NAME);
   if (cname.indexOf(className) == -1) {
    el.setAttribute(ATTR_CLASS_NAME, cname + " " + className);
   }
  }
  
  function removeClass(el, className) {
   var cname, arr = className.split(" ");
   if (cname = el.className) {
    if (className) {
     cname = " " + cname + " ";
     for (var i = arr.length; i--;) {
      cname = cname.replace(" " + arr[i] + " ", " ");
     }
     el.className = cname.substring(1, cname.length - 1);
    } else {
     el.className = "";
    }
   }
  }
  var nav = document.getElementById('nav');
  var links = nav.getElementsByTagName('a');
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
.style
for (var i = links.length; i--;) {
 links[i].style.display = "none";
 links[i].style.display = "";
}
ready
.className
for (var i = links.length; i--;) {
 addClass(links[i], "hide");
 removeClass(links[i], "hide");
}
ready
.setAttribute
for (var i = links.length; i--;) {
 addClass2(links[i], "hide");
 removeClass(links[i], "hide");
}
ready

Revisions

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