Введение¶
React Compiler — новый инструмент времени сборки, который автоматически оптимизирует приложение React. Он работает с обычным JavaScript и понимает Правила React, поэтому переписывать код, чтобы им пользоваться, не нужно.
Вы узнаете
- Что делает React Compiler
- Как начать работу с компилятором
- Стратегии постепенного внедрения
- Отладка и устранение неполадок, когда что-то идёт не так
- Использование компилятора в библиотеке React
Что делает React Compiler?¶
React Compiler автоматически оптимизирует приложение React во время сборки. React часто и без оптимизации достаточно быстр, но иногда приходится вручную мемоизировать компоненты и значения, чтобы приложение оставалось отзывчивым. Такая ручная мемоизация утомительна, в ней легко ошибиться, и она добавляет лишний код, который нужно сопровождать. React Compiler делает эту оптимизацию автоматически, снимая эту умственную нагрузку, чтобы вы могли сосредоточиться на создании возможностей.
До React Compiler¶
Без компилятора, чтобы оптимизировать повторные рендеринги, компоненты и значения нужно мемоизировать вручную:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Примечание
В этой ручной мемоизации есть тонкая ошибка, которая ломает мемоизацию:
1 | |
Хотя handleClick обёрнут в useCallback, стрелочная функция () => handleClick(item) создаёт новую функцию при каждом рендеринге компонента. Это значит, что Item всегда получает новый проп onClick, и мемоизация ломается.
React Compiler умеет оптимизировать это правильно и со стрелочной функцией, и без неё, гарантируя, что Item повторно рендерится, только когда меняется props.onClick.
После React Compiler¶
С React Compiler вы пишете тот же код без ручной мемоизации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Посмотрите этот пример в песочнице React Compiler
React Compiler автоматически применяет оптимальную мемоизацию и гарантирует, что приложение повторно рендерится, только когда это необходимо.
Какую мемоизацию добавляет React Compiler?
Автоматическая мемоизация React Compiler в первую очередь направлена на улучшение производительности обновлений (повторный рендеринг уже существующих компонентов), поэтому она сосредоточена на двух сценариях:
- Пропуск каскадного повторного рендеринга компонентов
- Повторный рендеринг
<Parent />заставляет повторно рендериться многие компоненты в его дереве, хотя изменился только<Parent />
- Повторный рендеринг
- Пропуск дорогих вычислений вне React
- Например, вызов
expensivelyProcessAReallyLargeArrayOfObjects()внутри компонента или хука, которому нужны эти данные
- Например, вызов
Оптимизация повторных рендерингов¶
React позволяет описывать интерфейс как функцию текущего состояния (конкретнее: пропсов, состояния и контекста). В текущей реализации, когда состояние компонента меняется, React повторно рендерит этот компонент и всех его потомков — если только вы не применили какую-то ручную мемоизацию с помощью useMemo(), useCallback() или React.memo(). Например, в следующем примере <MessageButton> будет повторно рендериться всякий раз, когда меняется состояние <FriendList>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
React Compiler автоматически применяет эквивалент ручной мемоизации и гарантирует, что при изменении состояния повторно рендерятся только нужные части приложения. Иногда это называют «мелкозернистой реактивностью». В примере выше React Compiler определяет, что возвращаемое значение <FriendListCard /> можно переиспользовать, даже когда friends меняется, и может избежать пересоздания этого JSX и повторного рендеринга <MessageButton>, когда счётчик меняется.
Дорогие вычисления тоже мемоизируются¶
React Compiler также может автоматически мемоизировать дорогие вычисления, которые используются во время рендеринга:
1 2 3 4 5 6 7 8 9 | |
Однако если expensivelyProcessAReallyLargeArrayOfObjects действительно дорогая функция, возможно, стоит реализовать для неё собственную мемоизацию вне React, потому что:
- React Compiler мемоизирует только компоненты и хуки React, а не каждую функцию
- Мемоизация React Compiler не разделяется между несколькими компонентами или хуками
Поэтому если expensivelyProcessAReallyLargeArrayOfObjects используется во многих разных компонентах, дорогое вычисление будет выполняться снова и снова, даже если передаются в точности те же элементы. Мы рекомендуем сначала профилировать и убедиться, что вычисление действительно настолько дорогое, прежде чем усложнять код.
Стоит ли попробовать компилятор?¶
Мы призываем всех начать использовать React Compiler. Сегодня компилятор всё ещё необязательное дополнение к React, но в будущем некоторым возможностям он может понадобиться, чтобы работать в полную силу.
Безопасно ли его использовать?¶
React Compiler теперь стабилен и тщательно проверен в производственной среде. Им уже пользуются в производственной среде такие компании, как Meta, но выкатка компилятора в производственную среду вашего приложения будет зависеть от состояния кодовой базы и от того, насколько хорошо вы следуете Правилам React.
Какие инструменты сборки поддерживаются?¶
React Compiler можно установить в нескольких инструментах сборки, таких как Babel, Vite, Metro и Rsbuild.
React Compiler — это в первую очередь лёгкая обёртка в виде плагина Babel вокруг ядра компилятора, которое спроектировано так, чтобы не зависеть от самого Babel. Начальная стабильная версия компилятора останется в первую очередь плагином Babel, но мы работаем с командами swc и oxc, чтобы сделать первоклассную поддержку React Compiler, и в будущем вам не придётся возвращать Babel в конвейеры сборки.
Пользователи Next.js могут включить React Compiler, вызываемый через swc, начиная с v15.3.1.
Что делать с useMemo, useCallback и React.memo?¶
По умолчанию React Compiler мемоизирует код на основе своего анализа и эвристик. В большинстве случаев эта мемоизация будет такой же точной или даже точнее той, что вы написали бы сами.
Однако иногда разработчикам нужен больший контроль над мемоизацией. Хуки useMemo и useCallback можно по-прежнему использовать вместе с React Compiler как аварийный люк, чтобы управлять тем, какие значения мемоизируются. Типичный случай — когда мемоизированное значение используется как зависимость эффекта, чтобы эффект не срабатывал повторно, даже если его зависимости по сути не изменились.
Для нового кода мы рекомендуем полагаться на компилятор в мемоизации и использовать useMemo/useCallback там, где нужен точный контроль.
Для существующего кода мы рекомендуем либо оставить текущую мемоизацию на месте (её удаление может изменить результат компиляции), либо тщательно протестировать код, прежде чем убирать мемоизацию.
Попробуйте React Compiler¶
Этот раздел поможет начать работу с React Compiler и понять, как эффективно использовать его в проектах.
- Установка — установите React Compiler и настройте его для инструментов сборки
- Совместимость версий React — поддержка React 17, 18 и 19
- Конфигурация — настройте компилятор под свои задачи
- Постепенное внедрение — стратегии постепенной выкатки компилятора в существующих кодовых базах
- Отладка и устранение неполадок — находите и исправляйте проблемы при использовании компилятора
- Компиляция библиотек — лучшие практики поставки скомпилированного кода
- Справочник API — подробная документация всех параметров конфигурации
Дополнительные материалы¶
Помимо этих документов мы рекомендуем заглянуть в рабочую группу React Compiler, где есть дополнительная информация и обсуждение компилятора.
Источник — https://react.dev/learn/react-compiler/introduction