Почему Chrome не нужно перерисовывать весь слой при изменении?

На практике я пытаюсь понять, как работает макет → краска → составной конвейер Chrome. Во время моего тестирования я запутался в поведении Chrome в следующей ситуации. (Codepen)

var button = document.querySelector('button');
var red = document.querySelector('.red');
var blue = document.querySelector('.blue');
button.addEventListener('click', function() {
  red.classList.toggle('test');
})
.wrapper {
  height: 100%;
  width: 100%;
  background-color: teal;
  position: static;
}

.square {
  height: 200px;
  width: 200px;
  position: static;
  transition: transform 0.3s ease,
    opacity 0.3s ease,
    width 0.3s ease,
    height 0.3s ease,
    box-shadow 0.3s ease;
}

.red {
  /* position: absolute; */
  background-color: red;
  top: 100px;
  left: 100px;
  /* will-change: transform; */
  opacity: 1;
}

.blue {
  background-color: blue;
  z-index: 3;
}

.test {
  /* transform: translate3d(50px, 50px, 0); */
  /* opacity: 0; */
  width: 60px;
  height: 60px;
  /* box-shadow: 0px 0px 0px 10px rgba(0,0,0,.5) */
}

button {
  position: fixed;
  right: 100px;
  top: 50px;
  z-index: 10000;
  font-weight: bold;
  background-color: yellow;
  padding: 5px 10px;
  /* will-change: transform; */
}
<div class="wrapper">
  <div class="red square"></div>
  <div class="blue square"></div>
</div>
<button>Click</button>

Ответы

Ответ 1

Итак, путающий бит здесь заключался в том, что мигание Paint инструментов Dev только мигает частью слоя, который становится недействительным из предыдущего кадра (поэтому, если один absolute позиционированный квадрат начинает уменьшаться, недействительная область между кадрами является площадь с размерами и координатами, которые квадрат имел в предыдущем кадре)

Однако внутренне весь слой перерисовывается, независимо от того, насколько велика или мала недействительные части между кадрами.

Так, например, мигающий курсор будет выглядеть небольшим на Paint Flashing, но на самом деле весь слой нужно перекрасить.

Действительно, если мы откроем панель "Производительность" и включим опцию "Расширенное рисование инструмента", мы увидим, что между квадратными переходами весь слой нарисован в обоих сценариях, описанных в вопросе.

Chrome Paint analysis 1

Chrome Paint analysis 2

источники

https://twitter.com/paul_irish/status/971196975013027840
https://twitter.com/paul_irish/status/971196996924030977
https://twitter.com/paul_irish/status/971197842713800704

Некоторые наблюдения

Если бы мы минимизировали шаги Layout and Painting, чтобы сделать как можно меньше операций, мы должны отделить красный квадрат и желтую кнопку от их собственных слоев рендеринга.

Этот способ взаимодействия с кнопкой и изменения размера квадрата влияет только на их соответствующие слои и не приведет к перерисовке фонового слоя (который включает фон и синий квадрат).