Does transform/opacity property invoke paint step in the browser conveyor

Viewed 187

Investigating how browser's render works I've noticed that in chrome dev tools with enabled flag paint flashing triggers paint step on changing transform/opacity property.

Look at these screenshots with code:

Example 1 (transform/opacity property)

let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
  elem.style.transform = `translate(${count}px,0)`;
  /// interchangeable
  /// elem.style.opacity = `${count/500}`;
  if(count++ < 500)
    requestAnimationFrame(anim);
  }
anim();
.newLayer{
  position:relative;
  width:150px;
  height:150px;
  background-color: red;
}
<div class="newLayer">I am a new Layer</div>
enter image description here

Example 2 (transform/opacity property with will-change)

let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
  elem.style.transform = `translate(${count}px,0)`;
  /// interchangeable
  /// elem.style.opacity = `${count/500}`;
  if(count++ < 500)
    requestAnimationFrame(anim);
  }
anim();
.newLayer{
  will-change: transform;
  position:relative;
  width:150px;
  height:150px;
  background-color: red;
}
<div class="newLayer">I am a new Layer</div>
enter image description here

It confuses me, because I've seen this one and this one sources, they say when you're using transform/opacity, paint stage is ommited. So what is it? Why do we see paint in the first example, and don't in second? Which one is lying?


Interesting one example with 2 paint operations:

let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
  elem.style.left = `${count}px`;
  if(count++ < 500)
    requestAnimationFrame(anim);
  }
anim();
.newLayer{
  position:relative;
  width:150px;
  height:150px;
  background-color: red;
}
<div class="newLayer">I am a new Layer</div>
enter image description here

Yes, there is used property of positioning, but look at the paint operations, one big stripe and one small such as in example without will-change. What does it mean (I am speaking about paint with tiny stripe length)?

Is the tiny paint block related with raster threads, what about big one?

1 Answers

Neither example is lying.

The browser minimises the number of layers it needs to composite together. It only creates a layer if it's given a reason to believe there'll be a benefit.

If you animate transform or opacity using CSS transitions, CSS animations, or web animations, the browser knows ahead of time that the element is animating in a way that might be optimised by creating a layer, so Chrome creates one for the duration of the animation.

If you animate using rAF, the browser doesn't have this foresight. will-change exists as a way to hint to the browser that it should create a layer for this element, depending on the changing property.

These are hints, and the browser isn't guaranteed to create a layer. There are other cases where some browsers create a layer, such as when another element needs to paint on top of a layer, and in the case of some other CSS like transform: translateZ(…).

Related