I am trying to understand, in practice, how the layout-> paint -> composite pipeline of modern browsers work.
My rough understanding is as follows:
- During the layout phase, the browser combines CSS with HTML information in order to figure out positions and dimensions of visual elements on screen. I also believe this is the time where it also determines how many render layers are there (due to
will-change for example)
- During the paint phase, the browser makes a framebuffer for each layer, containing information about what color each pixel should display, based on the layout data.
- During the compositing phase, the GPU composites all the layers together, based on the data generated during the paint phase, and sends the final result to the screen.
Based on the above understanding, there was something during my testing that confused me.
I have two squares, a red one and a blue one, inside a wrapper element. In Chrome’s dev tools this whole thing shows as one layer.
If both squares are
static positioned, when I transition the width and height of the red one, I can see that the whole layer gets repainted, which, to me, makes sense, since, if all 3 elements are in the same layer, changing the dimensions of one, changes the whole layer’s end result, so the whole layer has to be repainted.
If I set the red square to
absolute positioning, when I transition its width and height, even though the dev tools still show one layer, only the red square is shown as repainted.
Codepen (turn “Highlight repaints” on, in the dev tools, and click the button to toggle the size of the red square. Try doing it after changing the
position of the red square too.)
The second scenario does not make sense to me. If the two squares and the wrapper element are all in the same layer, as shown in the Chrome’s dev tools, shouldn’t, again, changing one element affect the whole layer and cause the layer as a whole to repaint? (I mean when the square shrinks, there is more of the wrapper and the other square revealed, that has to be filled with color, thus “repainted”)
Does Chrome, during the layout phase (or whatever phase it is that determines the layers) separate some elements into their own layers (due to
position properties for example), thus being able to repaint them separately, but after the compositing phase dumps them, so the developer only sees “one” layer in the dev tools?