Как оптимизировать компонент в React?
Рендеринг и производительность
Оптимизация компонента — это ответ на вопрос, что именно дорого: частота рендеров, стоимость одного рендера или объём DOM.
Шаг 0: измерить
React DevTools Profiler на production-сборке: сколько раз рендерится компонент, сколько стоит рендер и почему он произошёл («Record why each component rendered»).
Уменьшить частоту рендеров
- Структура состояния (первое, что нужно проверить): спустить часто меняющийся state вниз; children-как-проп, чтобы обёртка не рендерила детей; разделить контексты; сузить селекторы стора.
- React.memo на компоненте — пропускает рендер при поверхностно равных props.
- useCallback/useMemo у родителя — стабильные ссылки для props memo-ребёнка (иначе memo не работает; помнить про children и инлайн-объекты).
Удешевить сам рендер
useMemoдля тяжёлых вычислений (фильтрация, сортировка, агрегации).- Не создавать в рендере лишние объекты/функции; константы — за пределами компонента.
- Разбить «компонент-бог» на части: меняющаяся часть рендерится отдельно от статичной.
Уменьшить объём
- Виртуализация длинных списков — самая эффективная мера при тысячах узлов.
- Не рендерить невидимое (вкладки, модалки),
React.lazyдля тяжёлых блоков.
Сохранить отзывчивость
useTransition/useDeferredValue для несрочных тяжёлых обновлений; дебаунс дорогих реакций на ввод.
Мера
Мемоизировать всё подряд вредно: сравнение стоит ресурсов, код усложняется, цепочка ломается от одного нестабильного пропа. React Compiler (React 19) автоматизирует эту часть.
Коротко для собеседования
Профилировать → понять причину. Частые рендеры: структура состояния (state вниз, children-как-проп, контексты, селекторы), затем React.memo + стабильные props. Дорогой рендер: useMemo, декомпозиция. Много узлов: виртуализация, lazy. Блокировка ввода: useTransition. Мемоизация — точечно, а не по умолчанию.