Заметки по практике HTML, CSS, JS
November 8

Рендеринг CSS и нагрузка на клиент-железо.

Почему виснут вкладки в Хроме.

Как рендеринг HTML | CSS | JS кода нагружает CPU, GPU и другие ресурсы клиентского компьютера.

Подробно опишу принципы, которые помогут оптимизировать производительность CSS и JavaScript-анимаций с учётом вычислений размеров, рендеринга и аппаратного ускорения, а также оценки нагрузки на CPU, GPU, память и другие ресурсы.
Проверяем, тестируем примеры кода. Пока что тут приводятся не полностью проверенные фрагменты. По мере использования - буду помечать апдейты.

1. Вычисления размеров при рендеринге

Браузеры при рендеринге страницы выполняют три основные стадии:

  • Layout (или Reflow) — определение размеров и положения элементов.
  • Paint — отрисовка элементов (цвет, фон, текст).
  • Composite — компоновка отдельных слоев, чтобы браузер мог рендерить содержимое быстрее.

Некоторые свойства требуют перерисовки (paint) или перерасчета положения и размеров (layout), что приводит к высокой нагрузке на CPU и в меньшей степени на GPU.

Примерные вычислительные затраты:

  • width/height в процентах (например, width: 85%) –– умеренные затраты на Reflow: при изменении процента ширина/высота пересчитываются при каждом изменении размеров родительского контейнера.
  • flex (например, flex: 1 1 45.23097482%) — высокие затраты на Reflow: требует больших вычислений из-за алгоритмов flex-контейнеров. Чем больше вложенных элементов с flex, тем сложнее браузеру пересчитывать размеры.
  • transform (особенно scale и translate)минимальные затраты на CPU и нагрузка переносится на GPU, поскольку transform не требует перерасчета layout. Трансформации не меняют размер контейнера и позволяют браузеру избегать пересчета всего layout.

2. Оптимальные свойства для анимации

Наиболее оптимальными свойствами для анимаций являются те, которые не вызывают Reflow и Paint, а работают только на этапе Composite, что эффективно задействует GPU для отрисовки и минимально нагружает CPU. К таким свойствам относятся:

  • transform: например, scale, translate, rotate.
  • opacity: изменение прозрачности также не вызывает перерасчёт layout.
  • filter: не меняет расположение элементов, но более затратен по сравнению с transform.

Эти свойства можно задействовать с помощью GPU-ускорения, что значительно снижает нагрузку на CPU.

3. Сравнение затратности свойств на CPU, GPU, память, кэш и swap

таблица свойств CSS по CPU, GPU, Memory, Cache и Swap
таблица затратности свойств CSS по CPU, GPU, Memory, Cache и Swap

Заключение: Наиболее «лёгкими» свойствами для анимаций с точки зрения производительности являются transform и opacity, так как они не вызывают Reflow и работают только на Composite. CPU затрачивает минимальные ресурсы, тогда как GPU обрабатывает анимацию и кэширует слои для Composite.

4. Способы оптимизации рендеринга

  • Использование will-change: укажите браузеру заранее, какие свойства изменятся (например, will-change: transform, opacity). Это помогает браузеру оптимально выделить ресурсы.
css
Copy code
.overlay {
    will-change: transform, opacity;
    transition: transform 0.3s ease, opacity 0.3s ease;
}
  • Избегание часто изменяемых свойств width, height, top, left, margin: изменения этих свойств вызывают Reflow и перерасчет layout, что приводит к высокой нагрузке на CPU. Вместо top и left используйте transform: translate().
  • Использование requestAnimationFrame для плавных анимаций: синхронизирует анимации с частотой обновления экрана, снижая нагрузку по сравнению с setInterval.
  • Снижение количества repaint и reflow: избегайте частых манипуляций с DOM. Если нужно изменить несколько элементов, делайте это в одном потоке или используйте Document Fragments.

5. Особенности GPU и аппаратного ускорения в Chrome

В большинстве современных систем Chrome включает аппаратное ускорение по умолчанию, особенно для transform и opacity. Однако некоторые фильтры (например, blur, grayscale) могут увеличивать нагрузку на GPU. Аппаратное ускорение также зависит от операционной системы:

  • На macOS и Windows GPU обрабатывает больше эффектов, чем на Linux.
  • Chrome также поддерживает аппаратное ускорение для некоторых WebGL элементов и видео-декодинга.

Подсказка: Чтобы проверить, какие элементы рендерятся на GPU, используйте в DevTools флажок "Show composited layer borders" — элементы, обработанные GPU, будут выделены.

Пример кода с оптимизированной анимацией

html
Copy code
<div class="home-screen">
    <div class="overlay"></div>
</div>
css
Copy code
.home-screen {
    position: relative;
    overflow: hidden;
}

.overlay {
    position: absolute;
    top: -100%; /* Исходное положение за пределами видимости */
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    will-change: transform;
    transition: transform 0.3s ease;
}

.overlay.open {
    transform: translateY(100%); /* Анимация открытия */
}
javascript
Copy code
let overlay = document.querySelector('.overlay');

function openOverlay() {
    overlay.classList.add('open');
}

function closeOverlay() {
    overlay.classList.remove('open');
}

Заключение

Для достижения плавных анимаций и минимальной нагрузки на CPU и GPU старайтесь использовать transform и opacity для анимаций и по возможности избегайте изменения свойств, вызывающих перерасчёт layout (width, height, left, top). При правильной оптимизации, включая will-change и requestAnimationFrame, можно значительно снизить нагрузку и добиться плавных анимаций даже на слабых устройствах.