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

Сравни способы оптимизации в React и объясни, когда выбирать каждый вариант.

Рендеринг и производительность

Оптимизация в React сводится к трём направлениям: меньше лишних рендеров, дешевле каждый рендер, меньше и позже грузим код. Выбор инструмента зависит от того, что именно тормозит.

Мемоизация рендеров

  • React.memo(Component) — пропускает перерендер, если props не изменились. Выбирать для «листовых» компонентов, которые часто получают те же props (строки таблиц, карточки).
  • useMemo — кеширует дорогое вычисление или ссылку на объект. Выбирать при тяжёлых преобразованиях данных и для стабильных ссылок в props/зависимостях.
  • useCallback — стабильная ссылка на функцию. Работает в паре с React.memo у детей.

memo, useMemo и useCallback работают только вместе: один «нестабильный» проп ломает всю цепочку.

Архитектурные приёмы (часто эффективнее мемоизации)

  • Спуск состояния вниз — держать часто меняющийся state в маленьком компоненте, а не в корне.
  • children как проп — обёртка со state не перерендеривает переданных детей:
const ScrollTracker = ({ children }) => {
  const [offset, setOffset] = useState(0);
  // children не перерендериваются при изменении offset
  return <div onScroll={(e) => setOffset(e.target.scrollTop)}>{children}</div>;
};
  • Разделение контекстов — отдельные контексты для редко и часто меняющихся данных.

Большие списки и отложенная работа

  • Виртуализация (react-window, react-virtuoso) — рендерить только видимые строки. Выбирать при сотнях+ элементов.
  • useDeferredValue / useTransition (React 18) — пометить обновление как несрочное, чтобы ввод не «замерзал» при тяжёлой перерисовке.

Загрузка кода

  • React.lazy + Suspense — код-сплиттинг по маршрутам и тяжёлым виджетам.

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

Сначала измерить (React DevTools Profiler), потом лечить: лишние рендеры — memo/useCallback/useMemo и правильная структура состояния; тяжёлые списки — виртуализация; блокирующий ввод — useTransition/useDeferredValue; большой бандл — React.lazy. Мемоизация — не по умолчанию везде, а точечно по результатам профилирования.

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