---
title: Оптимизация производительности
seo:
  title: Оптимизация производительности — React Developer
  description: Тема «Оптимизация производительности» для собеседования React Developer. Каким образом можно оптимизировать производительность React-приложения? Как использовать memoization для оптимизации компонентов?
---

[Все темы React Developer](/react-developer)

## <strong>Каким образом можно оптимизировать производительность React-приложения?</strong> [#q-14bee738d69b81a8841afde8813a99c7]

Оптимизация производительности React-приложения&#58;

{/* prettier-ignore */}
1. <strong>Использование</strong> <code>React&#46;memo</code>&#58;

    - Предотвращает ненужные повторные рендеры компонентов, если их пропсы не изменились.

    ```javascript
    const MyComponent = React.memo(function MyComponent(props) {
      // компонент
    });
    ```

1. <strong>Использование хуков</strong> <code>useMemo</code> <strong>и</strong> <code>useCallback</code>&#58;

    - Мемоизация значений и функций, чтобы избежать их пересоздания при каждом рендере.

    ```javascript
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    ```

1. <strong>Виртуализация списков</strong>&#58;

    - Рендеринг только видимых элементов списка с помощью библиотек, таких как <code>react&#45;window</code>.

    ```javascript
    import { FixedSizeList as List } from 'react-window';
    ```

1. <strong>Разделение кода (Code Splitting)</strong>&#58;

    - Динамическая загрузка компонентов с помощью <code>React&#46;lazy</code> и <code>React&#46;Suspense</code>.

    ```javascript
    const MyComponent = React.lazy(() => import('./MyComponent'));
    ```

1. <strong>Контроль обновлений с помощью</strong> <code>shouldComponentUpdate</code> <strong>или</strong> <code>PureComponent</code>&#58;

    - В классовых компонентах использовать <code>shouldComponentUpdate</code> или наследовать от <code>React&#46;PureComponent</code>.

    ```javascript
    class MyComponent extends React.PureComponent {
      // компонент
    }
    ```

1. <strong>Оптимизация изображений</strong>&#58;

    - Использование форматов изображений сжатого размера и отложенная загрузка (lazy loading).

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

:::note[Ссылки для изучения]

1. [Оптимизация производительности в React](https://ru.legacy.reactjs.org/docs/optimizing-performance.html)
   :::

---

## <strong>Как использовать</strong> <code>memoization</code> <strong>для оптимизации компонентов?</strong> [#q-14bee738d69b81d39b45d1d57f5e6614]

<strong>Мемоизация</strong> — это техника, которая позволяет оптимизировать
производительность компонентов, избегая повторных вычислений и рендеров, если
входные данные не изменились.

#### Основные хуки для мемоизации&#58;

{/* prettier-ignore */}
1. <code>useMemo</code>&#58;

    - Мемоизирует вычисленное значение.

    ```javascript
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    ```

1. <code>useCallback</code>&#58;

    - Сохраняет ссылку на функцию между рендерами, пока зависимости не изменились. Передаваемое выражение функции всё равно вычисляется при рендере, но useCallback может вернуть ранее сохранённую функцию.

    ```javascript
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
    ```

#### Пример использования&#58;

```jsx
import React, { useMemo, useCallback } from "react";

const MyComponent = ({ a, b }) => {
  const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

  const memoizedCallback = useCallback(() => {
    doSomething(a, b);
  }, [a, b]);

  return (
    <div>
      <div>{memoizedValue}</div>
      <button onClick={memoizedCallback}>Click me</button>
    </div>
  );
};

export default MyComponent;
```

Мемоизация с помощью <code>useMemo</code> и <code>useCallback</code> позволяет оптимизировать производительность компонентов, предотвращая ненужные вычисления и рендеры при неизменных входных данных.

:::note[Ссылки для изучения]

1. [Оптимизация производительности в React](https://ru.legacy.reactjs.org/docs/optimizing-performance.html)
   :::

---

## <strong>Что такое "глубокое сравнение" (</strong><code>deep comparison</code><strong>) в контексте оптимизации производительности React?</strong> [#q-14bee738d69b8103a3acca07efca4610]

<strong>Глубокое сравнение</strong> — это процесс рекурсивной проверки всех
уровней вложенности объектов или массивов для определения их эквивалентности.

#### В контексте React&#58;

- React сравнивает зависимости useEffect, useMemo и useCallback через Object.is, без глубокого обхода. Глубокое сравнение нужно реализовать явно, например в пользовательской функции сравнения memo, и сначала измерить его стоимость.

- <strong>Цель</strong>&#58; Оптимизация производительности путем предотвращения
  ненужных рендеров, когда значения не изменились на глубоком уровне.

#### Пример&#58;

Антипример&#58; добавление isEqual в зависимости не включает глубокое сравнение. Код ниже по-прежнему сравнивает data по Object.is и вообще не вызывает isEqual.

```jsx
import { useEffect } from "react";
import isEqual from "lodash.isequal";

const MyComponent = ({ data }) => {
  useEffect(() => {
    // Действия при изменении data
  }, [data, isEqual]);

  return <div>{/* компонент */}</div>;
};
```

Глубокое сравнение может стоить дороже повторного рендера. Обычно сначала сохраняют стабильные ссылки и упрощают зависимости; специальный компаратор применяют только после измерения и с учётом всех значимых полей, включая функции.

:::note[Ссылки для изучения]

1. [Оптимизация производительности в React](https://ru.legacy.reactjs.org/docs/optimizing-performance.html)
   :::
