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

Какие свойства CSS самые тяжёлые для браузера?

2.2 Middle🔥 121 комментариев
#HTML и CSS

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

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

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

Самые тяжёлые CSS свойства для браузера — это те, которые требуют частого пересчёта layout, repaint и reflow: box-shadow, transform, opacity, filter, border-radius с градиентами. Их нужно использовать осторожно для высокопроизводительных анимаций.

1. Дорогие свойства CSS

/* ❌ САМЫЕ ТЯЖЁЛЫЕ */

/* Требует reflow (пересчёт layout дерева) */
width, height /* Меняют размер */
padding, margin /* Влияют на расположение */
display /* Меняет поток документа */
position /* Меняет позицию */
left, right, top, bottom /* Смещение (обычно) */
float /* Влияет на соседей */
flex-direction, grid-template /* Меняют layout */
box-sizing /* Меняет расчёты размеров */
line-height /* Влияет на высоту строк */
letter-spacing /* Влияет на ширину текста */

/* Требует repaint (перерисовка пикселей) */
color /* Перерисовка текста */
background /* Перерисовка фона */
border /* Перерисовка границ */
text-shadow /* Перерисовка с тенью */
box-shadow /* Требует расчётов тени */
outline /* Перерисовка контура */

/* Требует GPU и композиции */
filter /* Очень дорого (blur, brightness и т.д.) */
opacity /* Требует слоя */
mix-blend-mode /* Требует GPU */

/* ✅ ДЕШЁВЫЕ */
transform /* Использует GPU, не требует reflow */
transform-origin /* Не требует reflow */
will-change /* Помощь браузеру оптимизировать */

2. Почему transform дешевле, чем left/top

/* ❌ ДОРОГО — требует reflow */
.box {
  position: relative;
  left: 100px;
  animation: move 1s ease-in-out;
}

@keyframes move {
  0% { left: 0px; }
  100% { left: 100px; }
}

/* Браузер каждый кадр пересчитывает layout */
/* Timeline: Event -> Parse -> Compute -> Layout -> Paint -> Composite */

/* ✅ ДЕШЕВО — использует GPU */
.box {
  animation: move 1s ease-in-out;
}

@keyframes move {
  0% { transform: translateX(0); }
  100% { transform: translateX(100px); }
}

/* Браузер пропускает Layout & Paint, только Composite */
/* Timeline: Event -> Parse -> Compute -> Composite */

3. Тяжёлые фильтры и теневые эффекты

/* ❌ ОЧЕНЬ ДОРОГО */
.image {
  filter: blur(10px) brightness(1.5) contrast(1.2) saturate(1.5);
  /* Каждый фильтр требует отдельной операции GPU */
}

.card {
  box-shadow:
    0 10px 30px rgba(0,0,0,0.3),
    inset 0 1px 0 rgba(255,255,255,0.5),
    0 0 50px rgba(0,0,0,0.2);
  /* Множественные тени требуют много расчётов */
}

/* ✅ ЛУЧШЕ — минимум фильтров */
.image {
  filter: blur(5px); /* Один фильтр быстрее, чем несколько */
}

.card {
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
  /* Одна тень вместо трёх */
}

4. Граница (border) vs box-shadow

/* ❌ Медленно — требует repaint */
.button {
  border: 3px solid blue;
}

/* ✅ Быстрее для анимации */
.button {
  box-shadow: inset 0 0 0 3px blue;
  /* Но стоп, это тоже дорого! */
}

/* ✅ ЛУЧШЕ — используй transform и outline */
.button {
  outline: 3px solid blue;
  outline-offset: 2px;
  /* Outline не влияет на layout и быстрее */
}

5. Правильное использование will-change

/* ❌ Плохо — скажем браузеру о всех свойствах */
.animated {
  will-change: all;
  /* Браузер выделяет ресурсы на ВСЁ */
  /* Это замораживает браузер! */
}

/* ✅ Хорошо — специфицируем свойства */
.animated {
  will-change: transform, opacity;
  /* Браузер подготавливает только необходимое */
}

/* ✅ ЕЩЕ ЛУЧШЕ — добавляем в момент анимации */
.button:hover {
  will-change: transform;
  transform: scale(1.05);
}

.button:not(:hover) {
  will-change: auto; /* Убираем hint когда не нужен */
}

6. Содержание (containment) для изоляции

/* ✅ Отличное решение для performance */
.card {
  contain: layout style paint;
  /* Браузер изолирует это содержимое */
  /* Изменения внутри не влияют на внешних */
}

.grid-item {
  contain: content;
  /* Эквивалент layout + style + paint */
}

/* Так браузер не пересчитывает весь документ */
/* если изменился один карточка */

7. Сравнение производительности разных подходов

// Анимация скоростью 60fps требует < 16ms на кадр

// ❌ МЕДЛЕННО (много reflow)
const animate = () => {
  for (let i = 0; i < 100; i++) {
    elements[i].style.top = Math.random() * 100 + 'px';
    // Каждое присваивание = reflow
    // 100 reflow в 16ms = очень плохо
  }
};

// ✅ БЫСТРО (batch updates)
const animate = () => {
  const transforms = [];
  for (let i = 0; i < 100; i++) {
    transforms[i] = `translateY(${Math.random() * 100}px)`;
  }
  // Одна операция DOM
  elements.forEach((el, i) => {
    el.style.transform = transforms[i];
  });
};

// ✅ ЕЩЕ БЫСТРЕЕ (CSS animations)
// Используем CSS анимации вместо JavaScript
const animateWithCSS = () => {
  elements.forEach(el => {
    el.classList.add('animate');
  });
};

8. Плохие практики, которых избегать

/* ❌ Дорого — изменение много свойств layout */
.box:hover {
  padding: 20px; /* reflow */
  margin: 10px; /* reflow */
  width: 300px; /* reflow */
  height: 300px; /* reflow */
  border: 5px solid blue; /* repaint */
  background: lightblue; /* repaint */
  /* 6 операций браузера! */
}

/* ✅ Лучше — комбинируем в одно свойство */
.box:hover {
  transform: scale(1.1);
  background: lightblue;
  /* Только 1 composite operation + 1 repaint */
}

9. Инструменты для профилирования

// Используй DevTools Performance
// 1. Откройте DevTools (F12)
// 2. Performance tab
// 3. Нажмите Record
// 4. Выполните действие
// 5. Нажмите Stop
// 6. Посмотрите Layout/Paint/Composite в timeline

// Зелёная область = работает хорошо
// Красная область = проблемы

// Ищи:
// - Фиолетовые "Layout" события (reflow)
// - Зелёные "Paint" события (repaint)
// - Оранжевые "Composite" события (должны быть)

// Идеально: только Composite (синий цвет)

10. Чек-лист производительности CSS

const performanceChecklist = {
  animations: {
    use: 'transform, opacity', // Вместо left, top, width, height
    avoid: 'box-shadow, border-radius в анимациях',
  },
  
  filters: {
    minimize: 'Используй максимум 2-3 фильтра',
    avoid: 'blur + яркость + насыщенность одновременно',
  },
  
  layout: {
    use: 'flexbox, grid вместо float',
    avoid: 'Частые изменения width, height, padding, margin',
  },
  
  shadows: {
    use: 'Одна box-shadow вместо нескольких',
    avoid: 'Множественные тени на быстро движущихся элементах',
  },
  
  containment: {
    use: 'contain: layout style paint для изолированного контента',
    avoid: 'Забывать о содержании (containment)',
  },
};

Золотое правило: используй transform и opacity для анимаций, избегай layout-changing свойств (width, height, padding, margin) в движущихся элементах, применяй CSS containment для больших списков.