В конце прошлого года в Chrome появилась небольшая, но полезная оптимизация CSS-анимаций. Браузер перестал считать любое упоминание
width или height безусловной причиной выполнять анимацию на в основном потоке.Раньше даже такой код лишал
opacity возможности анимироваться на compositor:@keyframes fade {
from {
width: 200px;
opacity: 0;
}
to {
width: 200px;
opacity: 1;
}
}
Ширина здесь вообще не меняется, но одного присутствия width в keyframes было достаточно, чтобы Chrome счёл всю анимацию non-composited.В Chrome 144 это исправили. Blink теперь проверяет, действительно ли layout-зависимое свойство меняется между кадрами. Если значения одинаковые,
width или height больше не мешают opacity и transform работать на compositor.Особенно заметна эта оптимизация во View Transitions. Chrome сам генерирует для них анимации с
width и height, даже когда геометрия элемента остаётся прежней. До исправления такие переходы могли без необходимости фоллбека в основной поток.В первой реализации, правда, нашлась проблема с округлением:
97.984px
97.9844px
Формально значения разные, хотя визуально это один и тот же размер. Вскоре сравнение сделали нечётким, так что небольшая погрешность вычислений больше не отключает оптимизацию.Но чудес не произошло. Если размер действительно меняется:
@keyframes expand {
from {
width: 100px;
}
to {
width: 300px;
}
}
браузеру всё ещё приходится пересчитывать layout на каждом кадре. Такая анимация остаётся в основном потоке. Chrome не превращает её автоматически в transform: scale().Для подобных случаев в CSSWG обсуждают отдельный механизм, условный
size-animation, но к июлю 2026 года это всё ещё только предложение без готовой спецификации и реализации.Так что старое правило остаётся в силе: реально меняющиеся
width и height лучше без необходимости не анимировать. Chrome лишь убрал случай, когда неизменяющийся размер мешал нормальной compositor-анимации.#performance
