React: Performance
Здесь — React-специфичная оптимизация. Общую диагностику производительности (main thread, Web Vitals, layout thrashing) см. в Производительность рендеринга.
Какие методы оптимизации вы используете?
1. Мемоизация:
// React.memo — пропускает ре-рендер если пропсы не изменились
const List = React.memo(({ items }) => (
<ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>
));
// useMemo — мемоизирует тяжёлые вычисления
const sorted = useMemo(() => [...items].sort(compareFn), [items]);
// useCallback — стабильная ссылка на функцию
const handleClick = useCallback((id) => deleteItem(id), []);2. Code Splitting — разбиение бандла на чанки:
// React.lazy + Suspense — загружает компонент только при обращении
const HeavyChart = React.lazy(() => import('./HeavyChart'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<HeavyChart />
</Suspense>
);
}3. Ленивая загрузка роутов:
// React Router v6 — каждый роут загружается отдельным чанком
const Home = lazy(() => import('./pages/Home'));
const Profile = lazy(() => import('./pages/Profile'));
<Routes>
<Route path="/" element={<Suspense fallback={<Loader />}><Home /></Suspense>} />
<Route path="/profile" element={<Suspense fallback={<Loader />}><Profile /></Suspense>} />
</Routes>4. Избегать инлайновых объектов и функций в пропсах:
// ❌ Новая ссылка при каждом рендере → React.memo бесполезен
<Button onClick={() => doSomething()} style={{ color: 'red' }} />
// ✅ Стабильные ссылки
const handleClick = useCallback(() => doSomething(), []);
const style = useMemo(() => ({ color: 'red' }), []);
<Button onClick={handleClick} style={style} />Разбиение vendor-кода на уровне сборки (
splitChunks) — см. webpack.
Профилирование ре-рендеров
Без профилировщиков — базовые практики:
React.memoдля мемоизации компонентов.useMemo/useCallbackдля значений и функций.React.lazy+Suspenseдля разделения кода.- Избегать инлайновых функций/объектов в пропсах.
С профилировщиками:
React DevTools Profiler
→ Flame graph — показывает время рендера каждого компонента
→ Ranked chart — компоненты по убыванию времени рендера
why-did-you-render (пакет)
→ Логирует причины ре-рендеров в консоль
// Подключение why-did-you-render
import React from 'react';
import whyDidYouRender from '@welldone-software/why-did-you-render';
if (process.env.NODE_ENV === 'development') {
whyDidYouRender(React, { trackAllPureComponents: true });
}См. также
- rendering-performance — общая производительность и Web Vitals
- hooks — useMemo/useCallback
- webpack — splitChunks, разделение бандла