Перейти к содержимому
шпаргалка.
Esc
навигацияоткрыть⌘Jпредпросмотр
На этой странице

Оптимизация производительности

Все темы React Developer

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

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

  1. Использование React.memo:

    • Предотвращает ненужные повторные рендеры компонентов, если их пропсы не изменились.
    const MyComponent = React.memo(function MyComponent(props) {
      // компонент
    });
  2. Использование хуков useMemo и useCallback:

    • Мемоизация значений и функций, чтобы избежать их пересоздания при каждом рендере.
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);
  3. Виртуализация списков:

    • Рендеринг только видимых элементов списка с помощью библиотек, таких как react-window.
    import { FixedSizeList as List } from 'react-window';
  4. Разделение кода (Code Splitting):

    • Динамическая загрузка компонентов с помощью React.lazy и React.Suspense.
    const MyComponent = React.lazy(() => import('./MyComponent'));
  5. Контроль обновлений с помощью shouldComponentUpdate или PureComponent:

    • В классовых компонентах использовать shouldComponentUpdate или наследовать от React.PureComponent.
    class MyComponent extends React.PureComponent {
      // компонент
    }
  6. Оптимизация изображений:

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

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


Как использовать memoization для оптимизации компонентов?

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

Основные хуки для мемоизации:

  1. useMemo:

    • Мемоизирует вычисленное значение.
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  2. useCallback:

    • Сохраняет ссылку на функцию между рендерами, пока зависимости не изменились. Передаваемое выражение функции всё равно вычисляется при рендере, но useCallback может вернуть ранее сохранённую функцию.
    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);

Пример использования:

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;

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


Что такое “глубокое сравнение” (deep comparison) в контексте оптимизации производительности React?

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

В контексте React:

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

  • Цель: Оптимизация производительности путем предотвращения ненужных рендеров, когда значения не изменились на глубоком уровне.

Пример:

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

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

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

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

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

Эта страница была полезной?