PassFront
  1. PassFront
  2. База знаний
  3. Производительность в JS

Как избежать reflow?

Производительность в JS

Reflow избегают: анимируя через `transform`/`opacity`, группируя чтения и записи DOM, изменяя классы вместо стилей, используя `DocumentFragment`, избегая чтения геометрии в циклах.

Способы избежать/минимизировать reflow

Анимировать transform/opacity

Они идут на composite (GPU), не вызывают reflow/repaint:

/* Плохо — reflow */
.box { left: 100px; }
/* Хорошо — composite */
.box { transform: translateX(100px); }

Группировать чтения и записи DOM

Избегать layout thrashing (чередование чтения offsetHeight и записи → многократный reflow):

// Плохо — reflow на каждой итерации
for (const el of els) el.style.width = el.offsetWidth + 10 + 'px';

// Хорошо — сначала прочитать всё, потом записать
const widths = els.map((el) => el.offsetWidth);
els.forEach((el, i) => el.style.width = widths[i] + 10 + 'px');

Изменять класс, а не отдельные стили

el.classList.add('active'); // один reflow вместо нескольких

DocumentFragment для массовой вставки

const frag = document.createDocumentFragment();
items.forEach((item) => frag.append(createEl(item)));
container.append(frag); // один reflow

Скрыть элемент перед множеством изменений

display: none → изменения → показать (изменения не вызывают reflow, пока скрыт).

Избегать чтения геометрии без необходимости

offsetHeight, getBoundingClientRect вынуждают синхронный reflow — не в циклах.

position: absolute/fixed для анимируемых

Вынуть из потока — reflow не затрагивает соседей.

Коротко для собеседования

Reflow избегают: анимируя transform/opacity (composite, не layout), группируя чтения и записи DOM (против layout thrashing), меняя классы вместо стилей, DocumentFragment для массовой вставки, скрывая элемент перед множеством изменений, не читая геометрию (offsetHeight) в циклах, вынося анимируемое в absolute/fixed.

Другие вопросы раздела