Улучшения производительности React

В этом сообщении блога я объясню некоторые методы, которые вы можете использовать для повышения производительности вашего приложения ReactJS. Под производительностью я имею в виду производительность взаимодействия с пользователем, такую ​​как снижение медлительности или проблемы с зависанием.

Преждевременная оптимизация – корень всех зол

Я согласен с этой цитатой, но в то же время знание того, что может пойти не так, и предотвращение этого всегда является плюсом.

Причины медлительности в пользовательском интерфейсе

  • Ненужный повторный рендеринг компонентов.
  • В пользовательском интерфейсе отображается слишком много данных.

В этой статье я сконцентрируюсь на первом пункте.

Предотвращение ненужных повторных рендеров

Использование компонентов Memoized / Pure

React по умолчанию этого не перерисовывает компоненты. Когда компонент обновляется (изменяется состояние / реквизиты), все его дочерние компоненты повторно визуализируются. Чтобы избежать этого, мы оборачиваем дочерний компонент с помощью React.memo

Например: ссылка Codesandbox

В приведенном выше примере у нас есть компонент приложения, у которого есть поле ввода, изменяющее состояние input, и у нас есть компонент Counter, который имеет кнопку, увеличивающую значение count. У нас также есть console.log, который печатается при каждом повторном рендеринге компонента Counter.

Когда вы нажимаете кнопку, счетчик увеличивается и запускается console.log. Это нормально, потому что состояние нашего компонента (count) изменяется, поэтому наш компонент перерисовывается.
Теперь, когда вы введете текст в поле ввода, вы снова увидите, что запускается console.log. Этого не должно происходить, потому что Counter и свойства не меняются.
Поэтому, чтобы избежать этого ненужного повторного рендеринга, мы оборачиваем компонент Counter в оболочку React.memo. Делая это, мы запомнили наш компонент, что означает, что когда нет изменений во входных данных, выход не будет изменяться.

Использование React.useCallback для свойств функций

Когда вы отправляете функцию обратного вызова в качестве опоры, всякий раз, когда ваш компонент обновляет, новая ссылка на функцию будет создана и передана дочернему элементу, который заставляет дочерний элемент повторно визуализироваться. Чтобы этого избежать, мы используем React.useCallback.

Например: ссылка Codesandbox

Я изменил предыдущий пример, добавив дополнительную опору clearInput(функцию обратного вызова).
Эта функция очищает поле ввода. Теперь, когда вы вводите поле ввода, Counte повторно отображается, потому что ссылка на функцию изменяется каждый раз, когда вы изменяете состояние ввода.
Чтобы этого избежать, мы создаем функцию обратного вызова с React.useCallback и в качестве ее зависимости setInput.
Теперь, если вы введете текст, Counter не будет повторно отрисован.

Использование React.useMemo для свойств объекта.

Подобно функциям, когда вы отправляете объект в качестве опоры, всякий раз, когда ваш компонент обновляется, будет создана новая ссылка на объект (даже если значение объекта такое же) и передана дочернему элементу, который заставляет дочерний элемент повторно визуализироваться. Чтобы этого избежать, мы используем React.useMemo.

Например: ссылка Codesandbox

Я изменил предыдущий пример, добавив еще одно поле ввода и дополнительную опору data.
Это свойство data зависит от двух состояний input, поэтому оно меняется всякий раз, когда мы вводим второе поле ввода. Но это не должно изменяться, когда мы вводим текст в первое поле ввода.
Чтобы исправить это, мы создаем объект data, используя React.useMemo и input в качестве его зависимости.
Теперь, если вы введете в первое поле ввода, Counter не будет повторно отрисован.

Теперь наше приложение React работает. Если у вас простое приложение, эти оптимизации не имеют большого значения. Но если ваше приложение уже демонстрирует признаки медлительности, эти изменения определенно будут иметь значение. Кроме того, прежде чем начинать оптимизацию приложения, используйте инструменты разработки React, чтобы легко определить, какие компоненты вызывают проблемы.

Ответить