Когда использовать React.memo(), а когда нет

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

React.memo() — введенный в React 16.8.0, аналогичный PureComponent для компонентов класса, предоставляет метод, который помогает нам управлять повторным рендерингом компонентов. За счет ограничения повторного рендеринга компонентов React производительность пользовательского интерфейса повышается. Соответственно, благодаря быстрому и отзывчивому пользовательскому интерфейсу, плавной навигации и плавной загрузке пользовательский опыт и взаимодействие с системой улучшаются.

Поскольку React.memo() является компонентом более высокого порядка, он может включать в себя обычные функциональные компоненты React. Когда компоненты React обертываются с помощью React.memo(), React визуализирует компонент и запоминает результат. Если реквизиты компонента остаются прежними до следующего рендеринга, React повторно использует запомненный результат. При этом повторный рендеринг пропускается, и React не обновляет DOM, что обеспечивает повышение производительности. Та же функциональность может быть реализована в компонентах класса с помощью PureComponent.

Итак, в каких ситуациях мы должны использовать или избегать использования React.memo()?

Когда использовать:

  1. Когда мы ожидаем, что функциональный компонент часто будет отображаться после первого рендеринга, как правило, с теми же реквизитами. Это может произойти, если родительский компонент заставляет дочерний компонент отрисовываться. В таких случаях было бы уместно применить мемоизацию к вашим компонентам.
  2. Когда у нас есть чисто функциональные компоненты. При одних и тех же реквизитах такие компоненты останутся теми же — всегда будут рендерить один и тот же результат.
  3. Когда наши компоненты имеют большой размер и содержат большое количество элементов пользовательского интерфейса, так что повторный рендеринг вызовет задержку ответа, которая будет заметна для пользователя.

Когда не использовать:

  1. Первый и наиболее очевидный случай, когда нам следует избегать использования React.memo(), — это когда мы не можем количественно оценить прирост производительности. Если вычислительное время повторного рендеринга нашего компонента — с этим компонентом более высокого порядка и без него — незначительно или отсутствует, то использование React.memo() было бы бесполезным.
  2. В некоторых случаях нам может потребоваться повторный рендеринг компонента с другими реквизитами.React.memo() по умолчанию выполняет проверку на равенство реквизитов, чтобы установить, равны ли реквизиты рендеринга компонента. Равенство вернет true только в том случае, если предыдущие реквизиты равны следующим реквизитам. Если наш компонент повторно отрисовывается с другими реквизитами, то эта проверка на равенство вернет false, заставляя React выполнять различие предыдущего и следующего реквизитов. Такой «изменчивый» компонент не должен быть обернут в React.memo() из-за этого бесполезного сравнения свойств и того факта, что React всегда будет выполнять 2 задания при каждом рендеринге. Это не только не дает прироста производительности, но и вредит производительности!
  3. Хотя обертывание компонентов класса в React.memo() возможно, это считается (и справедливо) плохой практикой и настоятельно не рекомендуется. Вместо этого расширение класса PureComponent является более желательным и гораздо более чистым способом обработки запоминания при работе с компонентами класса.

Варианты использования и ситуации, в которых следует избегать использования React.memo(), включают, помимо прочего, вышеупомянутые случаи.

Строго используйте React.memo() для повышения производительности приложений с компонентами, которые часто перерисовываются. Однако имейте в виду, что компоненты React всегда будут повторно отображаться при изменении состояния — независимо от того, заключен ли компонент в React.memo() или нет.

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Получите эксклюзивный доступ к возможностям написания и советам в нашем сообществе Discord.