display:none vs visibility:hidden vs scale3d vs translate3d (v5)

Revision 5 of this benchmark created on


Description

What are the differences in performance and UX for using display:none, visibility:hidden, and opacity:0. Most of us know that display:none takes an element out of the render completely, and so if an element is in the layout flow, visibility:hidden will leave it there. However, it may not be clear that even though this is the case, an element with visibility:hidden does NOT intercept click events. This all related, but what this jsPerf instance tests is the performance of changing an Moderately positioned element's left style in these various states.

NOTE: I'm using opacity, which is not supported in IE < 9.

ADDING cases for scale3d and translate3d methods of hiding elements.

Preparation HTML

<div class="container">
  <div class="pretty display-none">display:none</div>
  <div class="pretty visibility-hidden">visibility:hidden</div>
  <div class="pretty opacity-zero">opacity:0</div>
  <div class="pretty opacity-minimal">opacity:0.5</div>
  <div class="pretty opacity-minimal">opacity:0.5</div>
  <div class="pretty scale-hide">scale3d</div>
  <div class="pretty translate-hide">translate3d</div>
</div>

<style>
  .container {
    position:relative;
    height:400px
  }
  .pretty {
    background:url(http://placekitten.com/500/300);
    width:500px;
    height:300px;
    position:absolute;
    top:0;
    left:0;
    color:white;
    text-align:center;
  }
  .display-none {
    display:none;
  }
  .visibility-hidden {
    visibility:hidden;
  }
  .opacity-zero {
    opacity:0;
  }
  .opacity-minimal {
    opacity:0.5;
  }
  .scale-hide {
    -webkit-transform: scale3d(0,0,0);
  }
  .translate-hide {
    -webkit-transform: translate3d(-1000000px,-1000000px,0);
  }

</style>
<script>
  window.DISPLAY_TEST_INDEX = 0;
</script>

Setup

var
      elementClass = null,
      period = 10000,
      radius = 50;
    
    function move() {
      window.DISPLAY_TEST_INDEX++;
      var
        element = document.getElementsByClassName(elementClass)[0],
        left = radius * Math.cos(window.DISPLAY_TEST_INDEX / period * 360),
        top = radius * Math.sin(window.DISPLAY_TEST_INDEX / period * 360)
    
      element.style.setProperty("left", left + "px");
      element.style.setProperty("top", top + "px");
    }

Test runner

Ready to run.

Testing in
TestOps/sec
display:none
elementClass = "display-none";
move();
ready
visibility:hidden
elementClass = "visibility-hidden";
move();
ready
opacity:0
elementClass = "opacity-zero";
move();
ready
opacity:0.5
elementClass = "opacity-minimal";
move();
ready
scale3d
elementClass = "scale-hide";
move();
ready
translate3d
elementClass = "translate-hide";
move();
ready

Revisions

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