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

Если в процессе рендеринга поменять CSS свойства, какие этапы рендеринга будут перезапущены

1.3 Junior🔥 231 комментариев
#HTML и CSS

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Этапы рендеринга браузера и изменение CSS

Это важный вопрос о производительности фронтенда. Давай разберёмся, как браузер обрабатывает изменения CSS и какие этапы рендеринга перезапускаются.

Этапы рендеринга (Critical Rendering Path)

Браузер выполняет эти этапы для отображения страницы:

  1. Parse HTML — парсинг HTML в DOM
  2. Parse CSS — парсинг стилей в CSSOM (CSS Object Model)
  3. Create Render Tree — объединение DOM + CSSOM
  4. Layout (Reflow) — расчёт координат и размеров элементов
  5. Paint (Repaint) — отрисовка пикселей
  6. Composite — объединение слоёв (для GPU ускорения)

Изменение CSS свойств во время рендеринга

Зависит от типа CSS свойства:

Тип 1: Layout свойства (вызывают Reflow)

Layout свойства влияют на размеры и позицию элементов:

  • width, height
  • margin, padding
  • top, left, right, bottom
  • display
  • position
  • float
  • flex, grid свойства
// При изменении layout свойств перезапускаются:
// Layout -> Paint -> Composite

const element = document.getElementById("box");

// Это вызывает REFLOW (Layout + Paint + Composite)
element.style.width = "200px"; // Layout изменился

// Это тоже вызывает REFLOW
element.style.margin = "20px";

// Это тоже вызывает REFLOW
element.style.position = "absolute";

Тип 2: Paint свойства (вызывают Repaint, но НЕ Reflow)

Paint свойства влияют только на визуальное отображение, не на размеры:

  • background-color
  • color
  • border-color
  • opacity
  • box-shadow
  • text-shadow
  • outline
// При изменении paint свойств перезапускаются:
// Paint -> Composite (Layout пропускается)

const element = document.getElementById("box");

// Это вызывает REPAINT (Paint + Composite), но НЕ Reflow
element.style.backgroundColor = "red"; // Нет Layout

// Это вызывает REPAINT
element.style.color = "blue";

// Это вызывает REPAINT
element.style.boxShadow = "0 0 10px black";

Тип 3: Composite свойства (САМЫЕ БЫСТРЫЕ)

Composite свойства — это свойства, которые обрабатываются GPU и не требуют Reflow или Repaint:

  • transform
  • opacity (иногда, смотря на реализацию)
// При изменении composite свойств перезапускается:
// Composite (БЕЗ Layout и Paint)

const element = document.getElementById("box");

// Это САМОЕ БЫСТРОЕ изменение
element.style.transform = "translateX(100px)"; // Только Composite

// Это также очень быстро
element.style.transform = "scale(1.5)";

// Это медленнее, но все ещё хорошо
element.style.transform = "rotate(45deg)";

Пример: Как браузер обрабатывает изменения

// Сценарий 1: Layout свойство
const box = document.getElementById("box");

// Шаг 1: Измени width
box.style.width = "300px";
// Браузер: Parse CSS -> Create Render Tree -> Layout -> Paint -> Composite

// Результат: вся цепочка перезапускается (МЕДЛЕННО)
// Сценарий 2: Paint свойство
const box = document.getElementById("box");

// Шаг 1: Измени цвет фона
box.style.backgroundColor = "red";
// Браузер: (Layout ПРОПУСКАЕТСЯ) -> Paint -> Composite

// Результат: быстрее, чем layout изменения
// Сценарий 3: Transform (самое быстрое)
const box = document.getElementById("box");

// Шаг 1: Сдвини с помощью transform
box.style.transform = "translateX(100px)";
// Браузер: (Layout и Paint ПРОПУСКАЮТСЯ) -> Composite

// Результат: максимально быстро! GPU обрабатывает

Практический пример: Animation

// ПЛОХАЯ АНИМАЦИЯ (Layout вычисляется каждый frame)
function animateBadly() {
  let position = 0;
  const element = document.getElementById("box");
  
  const interval = setInterval(() => {
    position += 5;
    // Это вызывает REFLOW каждый frame!
    element.style.left = position + "px";
    
    if (position > 500) clearInterval(interval);
  }, 16); // ~60 FPS
}

// ХОРОШАЯ АНИМАЦИЯ (использует Transform)
function animateWell() {
  let position = 0;
  const element = document.getElementById("box");
  
  const interval = setInterval(() => {
    position += 5;
    // Это вызывает только Composite!
    element.style.transform = `translateX(${position}px)`;
    
    if (position > 500) clearInterval(interval);
  }, 16); // ~60 FPS
}

// ЛУЧШАЯ АНИМАЦИЯ (CSS Animation)
const style = document.createElement("style");
style.textContent = `
  @keyframes slide {
    from { transform: translateX(0); }
    to { transform: translateX(500px); }
  }
  .sliding {
    animation: slide 1s ease-out;
  }
`;
document.head.appendChild(style);

const element = document.getElementById("box");
element.classList.add("sliding");
// Браузер оптимизирует это и работает очень быстро

CSS свойства, которые вызывают Reflow

Полный список:

// Размеры
"width", "height", "padding", "margin", "border-width",

// Позиция
"top", "left", "right", "bottom",

// Layout
"display", "position", "float", "clear",

// Flexbox/Grid
"flex", "flex-direction", "flex-wrap", "grid",

// Overflow
"overflow", "overflow-x", "overflow-y",

// Текст
"font-size", "font-weight", "line-height", "text-align",

// Трансформация (иногда)
"transform-origin" // Сам transform НЕ вызывает reflow!

Оптимизация CSS изменений

Вариант 1: Используй transform вместо left/top

// React компонент
interface BoxProps {
  x: number;
  y: number;
}

export function Box({ x, y }: BoxProps) {
  return (
    <div
      style={{
        transform: `translate(${x}px, ${y}px)`, // Быстро
        // НЕ используй:
        // left: x + "px", // Медленно
        // top: y + "px"
      }}
    />
  );
}

Вариант 2: Используй CSS классы вместо inline стилей

// styles.css
.box-active {
  background-color: red;
  box-shadow: 0 0 10px black;
}

// React
export function Box({ isActive }: { isActive: boolean }) {
  return (
    <div className={isActive ? "box box-active" : "box"} />
  );
}

// Браузер оптимизирует переход класса лучше,
// чем прямое изменение стилей

Вариант 3: Используй CSS animations

/* Браузер оптимизирует CSS анимации лучше всего */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in {
  animation: fadeIn 0.3s ease-out;
}
export function FadeInComponent() {
  return <div className="fade-in">Content</div>;
}

Вариант 4: Батчируй изменения

// ПЛОХО — 3 перерисовки
const element = document.getElementById("box");
element.style.width = "200px";
element.style.height = "200px";
element.style.backgroundColor = "red";

// ХОРОШО — 1 перерисовка
const element = document.getElementById("box");
element.style.cssText = `
  width: 200px;
  height: 200px;
  background-color: red;
`;

Chrome DevTools для анализа

// Открой DevTools -> Performance вкладка
// Запиши производительность и смотри:
// - Фиолетовые полосы = Layout (Reflow)
// - Зелёные полосы = Paint (Repaint)
// - Жёлтые полосы = Composite

console.time("animation");
// ... animation code
console.timeEnd("animation");

Итог

При изменении CSS во время рендеринга:

  • Layout свойства (width, margin, position) -> Reflow + Paint + Composite (МЕДЛЕННО)
  • Paint свойства (color, background, shadow) -> Paint + Composite (быстрее)
  • Transform -> только Composite (БЫСТРО!)

Для оптимальной производительности используй transform для анимаций и перемещений элементов.

Если в процессе рендеринга поменять CSS свойства, какие этапы рендеринга будут перезапущены | PrepBro