Перерасчёт компоновки
Оригинальное название: reflow
Коротко
Этап работы браузера, на котором он заново вычисляет размеры и координаты элементов страницы после изменений, влияющих на геометрию (reflow, или layout).
Что такое «Перерасчёт компоновки»
Чтобы показать страницу, браузер проходит несколько этапов: вычисляет стили, раскладывает элементы, рисует их и собирает слои в итоговую картинку. Раскладка — самый связанный этап: ширина одного блока влияет на перенос строк в нём, высота — на положение всего, что ниже. Поэтому изменение размеров одного элемента может заставить браузер пересчитать компоновку большой части страницы. На больших каталогах и сложных формах это уже заметные миллисекунды.
Что вызывает перерасчёт
- Добавление и удаление элементов, изменение текста.
- Изменение свойств геометрии:
width,height,padding,margin,top,font-size,display. - Загрузка веб-шрифта или картинки без заданных размеров.
- Изменение размеров окна и поворот телефона.
- Чтение геометрии после изменения стилей. Свойства
offsetHeight,clientWidth,scrollTopи методgetBoundingClientRect()требуют актуальных значений, и браузер выполняет раскладку немедленно, вне очереди.
Пример: лишние перерасчёты в цикле
// плохо: чтение и запись чередуются — раскладка на каждой итерации
cards.forEach(card => {
card.style.height = card.offsetWidth * 0.75 + 'px';
});
// лучше: сначала все чтения, потом все записи
const widths = cards.map(card => card.offsetWidth);
cards.forEach((card, i) => {
card.style.height = widths[i] * 0.75 + 'px';
});
В первом варианте браузер после каждой записи вынужден пересчитать раскладку, чтобы ответить на следующее чтение. Такое явление называют layout thrashing. Во втором варианте раскладка выполняется один раз. А в этой конкретной задаче скрипт вообще не нужен: пропорции карточки задаёт свойство aspect-ratio: 4 / 3.
Как найти и уменьшить
Во вкладке Performance инструментов разработчика перерасчёты видны как блоки Layout, а принудительные помечаются предупреждением Forced reflow со ссылкой на строку кода. Основные приёмы:
- анимировать
transformиopacityвместо размеров и позиций; - указывать
widthиheightу картинок и резервировать место под баннеры, чтобы вёрстка не прыгала; - ограничивать область пересчёта свойством
contain— см. изоляцию компоновки; - группировать изменения DOM и выполнять их в
requestAnimationFrame.
После раскладки браузер обычно переходит к перерисовке, так что каждый лишний перерасчёт тянет за собой и её. Практический чек-лист по этим метрикам для одной из CMS — в статье об ускорении сайта на 1С-Битрикс.

