Search code examples
javascripthtmlcssweb-performancewill-change

Why does will-change:opacity treat fixed elements differently than will-change:transform in chrome?


I am trying to optimize the scrolling of my web app. I have data tables with tons of data, and scrolling gets pretty bad. I added will-change: transform to the data table but it broke my table headers that are position: fixed (I make them fixed to allow them to scroll with the viewport). The elements don't move with the viewport at all, they just stay stuck in the flow of the document.

But by chance I discovered that if I use will-change:opacity instead, my fixed headers are fine. Can someone explain this behavior? I haven't been able to find any documentation that says they should act differently.

Here is a code pen with an example of what I am talking about. Toggle between the values, and scroll in blue div. https://codepen.io/bkfarns/pen/aLYgrN

Here is the basic code from the pen too:

html:

  <div class="container">
    <div class="fixed">should be position: fixed</div>
    <div class="too-tall">div that is too tall</div>
  </div>

css:

.container {
    margin-left: 100px;
    background-color: blue;
    width:400px;
    height:300px;
    overflow: auto;
    will-change: transform;//changing this to opacity fixes the issue
}

.fixed {
  background-color: grey;
  position: fixed;
  margin-left: 150px;
  margin-top: 100px;
}

.too-tall {
  background-color: red;
  width: 90px;
  height: 600px;
}

Solution

  • The whole point of will-change is to make all possible changes that browser would have to apply when the specified property will change in advance, reducing the time needed for the change itself. Effectively it means that by specifying will-change:transform you make the element transformed (though visually it stays in the same position), and descendants of the transformed elements can't be fixed per the CSS Transforms spec. Opacity doesn't have such effect, so will-change:opacity doesn't break fixed positioning.

    Also, will-change per se doesn't have any "optimization magic", it only optimizes the changes of the specified properties. Some properties force the elements to the composite layers that theoretically can be processed by the GPU more efficiently, but if there is too many such elements it may have the opposite effect. For optimizing scrolling, probably other strategies would be more efficient.