Как оптимизировать рендеринг компонента в React?
Рендеринг и производительность
Оптимизация рендеринга сводится к двум вопросам: как рендерить реже и как сделать рендер дешевле. Начинать всегда с измерения — React DevTools Profiler покажет, что именно тормозит.
Рендерить реже
- React.memo — обернуть дорогой компонент, чтобы он пропускал рендер при неизменных props.
- useCallback / useMemo у родителя — стабилизировать ссылки на функции и объекты, которые идут в props мемоизированных детей (иначе memo не сработает).
- Спуск состояния вниз — часто меняющийся state (ввод, hover) держать в маленьком компоненте, а не в корне страницы.
- children как проп — компонент-обёртка со своим state не перерендеривает переданных детей:
const Collapsible = ({ children }) => {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(!open)}>toggle</button>
{open && children} {/* children созданы родителем — стабильны */}
</div>
);
};- Разделение контекстов — быстрые и медленные данные в разных провайдерах, value мемоизирован.
Сделать рендер дешевле
- useMemo для тяжёлых вычислений — сортировки, фильтрации, агрегации не считать заново каждый рендер.
- Виртуализация длинных списков (react-window) — рендерить только видимые элементы.
- useTransition / useDeferredValue — тяжёлые обновления пометить несрочными, чтобы не блокировать ввод.
- React.lazy — не рендерить (и не грузить) то, что не видно: модалки, вкладки, тяжёлые виджеты.
Правильный порядок действий
Профилировать → найти частые/дорогие рендеры → сначала исправить структуру (состояние не на своём уровне, толстый контекст), потом добавлять мемоизацию точечно. Мемоизация везде «на всякий случай» усложняет код и сама стоит ресурсов.
Коротко для собеседования
Сначала профилирование (React DevTools). Меньше рендеров: React.memo + useCallback/useMemo, спуск состояния, children-как-проп, раздельные контексты. Дешевле рендер: useMemo для вычислений, виртуализация списков, useTransition, React.lazy. Архитектурные правки обычно дают больше, чем тотальная мемоизация.