← Назад к вопросам

Сколько будет reflow в один кадр?

1.7 Middle🔥 121 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разбор понятий: reflow и frame

Прежде чем ответить на вопрос о количестве reflow в кадре, важно уточнить термины. Reflow (или layout) — это процесс вычисления геометрии элементов страницы: их размеров, позиций и взаимного расположения. Браузер должен определить точные координаты каждого элемента, чтобы отрисовать его на экране. Это дорогая операция, поскольку часто вызывает каскадные пересчеты дочерних и соседних элементов.

Кадр (frame) — это единица отрисовки в конвейере рендеринга браузера. В идеале браузер стремится к 60 кадрам в секунду (16.7 мс на кадр) для плавной анимации.

Сколько reflow происходит за один кадр?

Теоретически, в одном кадре может происходить множество reflow, но браузеры активно оптимизируют этот процесс, чтобы минимизировать их количество.

Стандартный цикл рендеринга и reflow

В идеальном сценарии для одного кадра браузер выполняет следующий конвейер:

  1. JavaScript → 2. Style calculation → 3. Layout (reflow) → 4. Paint → 5. Composite

Reflow происходит на этапе Layout. Однако браузер старается объединять несколько изменений DOM/CSS в один reflow, если это возможно. Ключевые моменты:

  • Синхронные вызовы свойств, требующих layout (например, offsetWidth, getComputedStyle), могут форсировать немедленный reflow, прерывая эту оптимизацию.
  • Современные браузеры используют такие техники, как incremental layout и dirty bit systems, чтобы пересчитывать только затронутые части дерева, а не всю страницу.

Пример: множественные reflow в одном кадре

Рассмотрим код, который вызывает несколько reflow из-за синхронного чтения геометрических свойств:

// ПЛОХО: вызывает несколько reflow в одном кадре
const element = document.getElementById('myElement');
element.style.width = '100px'; // Помечает layout как "грязный"
const width1 = element.offsetWidth; // СИНХРОННОЕ ЧТЕНИЕ → форсирует reflow
element.style.height = '200px'; // Снова помечает как "грязный"
const height1 = element.offsetHeight; // Ещё одно чтение → ещё один reflow

В этом примере произойдет два reflow в одном кадре (если код выполняется внутри одного таска, например, в requestAnimationFrame). Каждое чтение offsetWidth/offsetHeight заставляет браузер выполнить немедленный пересчет layout, чтобы вернуть актуальное значение.

Оптимизированный подход: одно изменение, один reflow

// ХОРОШО: один reflow на кадр
const element = document.getElementById('myElement');
// Все изменения стилей группируются
element.style.cssText = 'width: 100px; height: 200px;';
// Чтение свойств ВНЕ цикла изменений, если они нужны позже
requestAnimationFrame(() => {
  const width = element.offsetWidth; // Тут будет один reflow, если он ещё не был выполнен
});

Критически важные правила

  1. Браузер стремится к одному reflow за кадр в оптимальном сценарии, когда все изменения DOM/CSS сгруппированы, а чтение геометрических свойств происходит после записи (паттерн "чтение после записи").
  2. Если синхронно читать геометрические свойства между изменениями, количество reflow может вырасти до N+1, где N — количество таких чтений.
  3. Асинхронные API, такие как requestAnimationFrame, помогают координировать изменения с циклом рендеринга, минимизируя reflow.
  4. Современные фреймворки (React, Vue) используют виртуальный DOM и батчинг обновлений, чтобы снизить количество reflow.

Пример с batch-изменениями

// Демонстрация батчинга в современных браузерах
const container = document.getElementById('container');
// Браузер может объединить эти изменения в один reflow
for (let i = 0; i < 100; i++) {
  const div = document.createElement('div');
  div.textContent = `Item ${i}`;
  container.appendChild(div); // Теоретически 100 добавлений, но reflow может быть 1
}
// Но если здесь прочитать offsetHeight, произойдет reflow
console.log(container.offsetHeight);

Вывод

Количество reflow в одном кадре зависит от кода. В оптимальном случае — один (или даже нуль, если изменений layout нет). В наихудшем — десятки, если синхронно читать layout-свойства между множественными изменениями DOM. Ключевая задача разработчика — минимизировать количество reflow через:

  • Группировку изменений DOM.
  • Избегание синхронного чтения геометрических свойств в циклах.
  • Использование requestAnimationFrame для анимаций.
  • Применение CSS-свойств, которые не вызывают reflow (например, transform и opacity для анимаций).

Инструменты типа Performance Tab в Chrome DevTools позволяют точно анализировать, сколько reflow происходит в каждом кадре, и находить узкие места.

Сколько будет reflow в один кадр? | PrepBro