Какие знаешь способы оптимизации React-приложения?

👨‍💻 Frontend Developer 🟡 Часто попадается 🎚️ Сложный
#React

Краткий ответ

Основные способы оптимизации React-приложений:

  1. React.memo — предотвращает ненужные перерисовки компонентов 🔄
  2. useMemo — мемоизация дорогих вычислений 💰
  3. useCallback — предотвращает создание новых функций 📦
  4. Lazy loading — загрузка компонентов по необходимости ⏳
  5. Virtualization — отображение только видимых элементов списка 📋
// React.memo для компонента
const MemoizedComponent = React.memo(({data}) => <div>{data}</div>);
 
// useMemo для вычислений
const expensiveValue = useMemo(() => heavyCalculation(data), [data]);
 
// Lazy loading компонентов
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

Полный ответ

Оптимизация React-приложения — как уборка в комнате. Если всё бросать где попало, искать вещи будет тяжело и долго! 🧹

React.memo — предотвращение перерисовок

React по умолчанию перерисовывает компоненты при любом изменении:

// ❌ Проблема — лишние перерисовки
const ChildComponent = ({data}) => {
  console.log('Перерисовка!'); // Вызывается даже если data не менялась
  return <div>{data}</div>;
};
 
// ✅ Решение — React.memo
const OptimizedChild = React.memo(({data}) => {
  console.log('Перерисовка!'); // Вызывается только если data изменилась
  return <div>{data}</div>;
});

useMemo — мемоизация вычислений

Кэширование результатов дорогих операций:

// ❌ Проблема — вычисления при каждой перерисовке
const ExpensiveComponent = ({items}) => {
  const sortedItems = items.sort(); // Сортировка каждый раз!
  return <div>{sortedItems.length}</div>;
};
 
// ✅ Решение — useMemo
const OptimizedComponent = ({items}) => {
  const sortedItems = useMemo(() => items.sort(), [items]); // Только при изменении items
  return <div>{sortedItems.length}</div>;
};

useCallback — стабильные функции

Предотвращение создания новых функций:

// ❌ Проблема — новые функции при каждой перерисовке
const ParentComponent = () => {
  const handleClick = () => { /* ... */ }; // Новая функция каждый раз!
  
  return <ChildComponent onClick={handleClick} />; // Child перерисовывается
};
 
// ✅ Решение — useCallback
const OptimizedParent = () => {
  const handleClick = useCallback(() => { /* ... */ }, []); // Одна функция!
  
  return <ChildComponent onClick={handleClick} />; // Не перерисовывается
};

Lazy Loading — отложенная загрузка

Загрузка тяжёлых компонентов только при необходимости:

// ✅ Lazy loading
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
 
function App() {
  const [show, setShow] = useState(false);
  
  return (
    <div>
      <button onClick={() => setShow(true)}>Показать</button>
      {show && (
        <Suspense fallback="Загрузка...">
          <HeavyComponent />
        </Suspense>
      )}
    </div>
  );
}

Virtualization — виртуализация списков

Отображение только видимых элементов:

// ✅ Для больших списков
import {FixedSizeList as List} from 'react-window';
 
const VirtualizedList = ({items}) => (
  <List
    height={600}
    itemCount={items.length}
    itemSize={50}
  >
    {({index, style}) => (
      <div style={style}>{items[index]}</div>
    )}
  </List>
);

Другие способы оптимизации

Code Splitting

// ✅ Разделение кода на части
// Вместо одного большого бандла — несколько маленьких

Bundle Analysis

// ✅ Анализ размера бандла
// Проверка, что не попало лишнего

Production Build

// ✅ Всегда используй production сборку
// Development версия медленнее

Частые ошибки

Мемоизировать всё подряд

// ❌ Плохо — мемоизация тоже имеет стоимость
const OverOptimized = React.memo(({simpleProp}) => {
  return <div>{simpleProp}</div>; // Нет смысла мемоизировать простые компоненты
});
 
// ✅ Хорошо — мемоизировать сложные компоненты
const ReallyComplexComponent = React.memo(({expensiveData}) => {
  // Сложные вычисления
});

Игнорировать зависимости

// ❌ Ошибка — неправильные зависимости
const value = useMemo(() => calculate(data), []); // data не в зависимостях!
 
// ✅ Правильно — все зависимости указаны
const value = useMemo(() => calculate(data), [data]);

Простые правила

  1. React.memo — для предотвращения перерисовок компонентов 🔄
  2. useMemo — для кэширования дорогих вычислений 💰
  3. useCallback — для стабильных функций 📦
  4. Lazy loading — загружай только нужное ⏳
  5. Virtualization — показывай только видимое 📋
  6. Измеряй — сначала найди реальные проблемы 🔍
  7. Не переборщить — оптимизация тоже имеет стоимость ⚖️

Понимание способов оптимизации помогает создавать быстрые и плавные React-приложения! 💪


Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪