Performant React 101: `useEffect` или `useLayoutEffect`?

Front-end разработчики, работающие с React, постоянно используют хук useEffect для рендеринга побочных эффектов.
 
Но знаете ли вы, что существует похожий, но немного другой хук под названием useLayoutEffect? Я не знал, пока не наткнулся на экземпляр этого хука, используемый в одной из кодовых баз, в которую я вносил свой вклад.

Это блог о том, как понять разницу между ними и понять, когда и когда не стоит использовать каждый из них.

Разница

В двух словах, разница заключается в точности.

  • useEffect выполняется, но нет никакой гарантии, когда именно это произойдет. Это асинхронная операция, которая выполняется после компоновки и закрашивания пикселей.

  • useLayoutEffect, напротив, гарантированно выполняется немедленно. Это синхронная операция, которая выполняется после всех мутаций DOM и до того, как браузер сможет закрасить пиксели. Если вы знакомы с жизненным циклом componentDidMount в компонентах класса React, то это, по сути, эквивалентное поведение.

UseLayoutEffect кажется превосходным. Должны ли мы использовать его для всего?

Но почему бы нам не захотеть использовать useLayoutEffect постоянно?

Не так быстро. Как и во всем, точность имеет свою цену.

React оптимизировал useEffect, чтобы сделать его более производительным. При использовании React нам часто приходится программировать побочные эффекты, и повышение производительности, встроенное в useEffect, существенно увеличит производительность.

Команда React явно поощряет пользователей использовать useEffect как можно чаще, чтобы избежать блокировки визуальных обновлений.

По словам официальной документации React в разделе ‘Timing of effects’:

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

Побочное замечание: команда React недавно обновила useEffect в React 18, чтобы сделать его синхронным для таких распространенных событий, как нажатие кнопки мыши пользователем, что дает еще меньше причин для использования хука useLayoutEffect.

Так когда же следует использовать useLayoutEffect?

Обычно это сводится к одной основной причине:

Когда вам нужно измерить DOM и обеспечить немедленную визуальную обратную связь с расчетом (отсюда и “Layout” в названии).

Это важно, поскольку побочные эффекты не могут быть отложены.

  • В документах React приводится пример, когда мутация DOM вычисляется перед следующей закраской, чтобы пользователь не заметил визуальных несоответствий.

  • Это может включать специфические случаи использования, такие как анимация или перемещение объектов по DOM, которые требуют мгновенных вычислений и обратной связи. Использование useEffect для этих случаев, скорее всего, приведет к неровному и непоследовательному опыту.

Есть еще один случай использования: 

  • Как я упоминал выше, useLayoutEffect является эквивалентом старого жизненного цикла componentDidMount в компонентах класса React. Этот хук можно использовать для миграции с компонентов классов на компоненты функций, чтобы обеспечить замену один в один. Однако это должно быть временным решением.

Выводы

Думайте о useEffect как о своей надежной Toyota corolla: надежная, производительная и дешевая – идеально подходит для 99,9% случаев использования. С другой стороны, useLayoutEffect – это высококлассный Ferrari: быстрый, отзывчивый, но дорогой в использовании, предназначенный для 0,1% случаев, когда скорость действительно важна.

  • useEffect и useLayoutEffect оба используются для действия побочных эффектов, но последний позволяет вам более точно контролировать время его выполнения.

  • Используйте useEffect как можно чаще, чтобы воспользоваться преимуществами оптимизации производительности команды React. Существует очень мало реальных случаев использования useLayoutEffect . Используйте его только в том случае, если (1) вам нужно немедленно визуально показать побочные эффекты вашим пользователям, или (2) когда вы временно переходите от componentDidMount.

Оцените статью
Procodings.ru
Добавить комментарий