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

Зачем оптимизировать отрисовку?

1.0 Junior🔥 121 комментариев
#Оптимизация и производительность

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

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

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

Зачем оптимизировать отрисовку в веб-приложениях

Оптимизация отрисовки (rendering performance) — это критически важный аспект разработки современных веб-приложений. От неё зависит пользовательский опыт, производительность и даже финансовые результаты.

Почему это важно

1. Пользовательский опыт (UX) Медленная отрисовка приводит к задержкам и "зависаниям" интерфейса:

// Плохо — блокирует главный поток
function renderMillionItems() {
  const list = document.getElementById("list");
  for (let i = 0; i < 1000000; i++) {
    const item = document.createElement("div");
    item.textContent = "Item " + i;
    list.appendChild(item); // Каждое добавление триггерит reflow
  }
}
// Результат: UI зависает на 5+ секунд

// Хорошо — группирует операции
function renderMillionItemsOptimized() {
  const fragment = document.createDocumentFragment();
  for (let i = 0; i < 1000000; i++) {
    const item = document.createElement("div");
    item.textContent = "Item " + i;
    fragment.appendChild(item); // Без reflow
  }
  document.getElementById("list").appendChild(fragment); // Одна операция
}

2. Скорость страницы Медленные сайты теряют пользователей:

  • При задержке 1 сек конверсия падает на 7%
  • При задержке 3 сек — на 40%
  • Задержка в 1 сек — это потеря миллионов для крупных сервисов

3. Производительность на слабых устройствах Оптимизированный код работает везде:

// React пример неоптимизированного списка
function UserList({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>
          <UserCard user={user} /> {/* Перестраивается каждый раз */}
        </li>
      ))}
    </ul>
  );
}

// Оптимизированная версия
const UserCard = React.memo(({ user }) => (
  <div>
    <h3>{user.name}</h3>
    <p>{user.email}</p>
  </div>
));

function UserList({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>
          <UserCard user={user} /> {/* Не перестраивается если user не изменился */}
        </li>
      ))}
    </ul>
  );
}

Основные метрики производительности

1. FCP (First Contentful Paint) Время до первого контента на экране. Пользователь видит, что страница загружается.

2. LCP (Largest Contentful Paint) Время до загрузки самого крупного элемента. Нужно минимизировать <= 2.5 сек.

3. CLS (Cumulative Layout Shift) Как сильно смещаются элементы после загрузки. Должно быть <= 0.1.

// Плохо — смещает контент
<div>
  <img src="photo.jpg" /> {/* Размер неизвестен, потом смещает контент */}
  <h1>Title</h1>
</div>

// Хорошо — зарезервирует место
<div>
  <img src="photo.jpg" width={400} height={300} alt="photo" />
  <h1>Title</h1>
</div>

Основные техники оптимизации

1. Виртуализация списков Отрисовывает только видимые элементы:

// npm install react-window
import { FixedSizeList } from "react-window";

function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={35}
    >
      {({ index, style }) => (
        <div style={style}>{items[index]}</div>
      )}
    </FixedSizeList>
  );
}
// 100 тыс элементов отрисуются за O(1) время

2. Code splitting и ленивая загрузка

// Загружает компонент только когда нужен
const HeavyComponent = React.lazy(() => import("./Heavy"));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

3. Мемоизация и батчинг

// Предотвращает ненужные пересчёты
const expensiveResult = useMemo(() => {
  return calculateExpensive(data);
}, [data]);

// Группирует обновления в один render
const [count, setCount] = useState(0);
const handleClick = () => {
  flushSync(() => setCount(c => c + 1));
  // Сразу видит обновления
};

4. CSS оптимизация

/* Плохо — триггерит reflow при hover */
.button:hover {
  width: 150px; /* Меняет размер */
}

/* Хорошо — только repaint */
.button:hover {
  background-color: blue; /* Только цвет */
}

/* Лучше всего — use transform */
.button:hover {
  transform: scale(1.05); /* GPU ускорено */
}

Долгосрочные выгоды

  • Большище конверсия — быстрые сайты конвертят лучше
  • SEO рейтинг — Google учитывает скорость
  • Экономия энергии — меньше нагрузка на батарею пользователей
  • Масштабируемость — оптимизированный код растёт лучше
  • Конкурентное преимущество — пользователи выбирают быстрые сервисы

Оптимизация отрисовки — это не "nice to have", а обязательная часть профессиональной разработки.