Введение
React Compiler — это новый инструмент сборки, который автоматически оптимизирует ваше приложение React. Он работает с обычным JavaScript и понимает правила React, поэтому вам не нужно переписывать код, чтобы им пользоваться.
Вы узнаете
- Что делает React Compiler
- Как начать работу с компилятором
- Стратегии постепенного внедрения
- Отладка и устранение неполадок
- Использование компилятора в вашей библиотеке React
Что делает React Compiler?
React Compiler автоматически оптимизирует ваше приложение React во время сборки. React часто работает достаточно быстро и без оптимизации, но иногда для отзывчивой работы приложения приходится вручную мемоизировать компоненты и значения. Такая ручная мемоизация утомительна, в ней легко ошибиться, а код становится сложнее поддерживать. React Compiler выполняет эту оптимизацию автоматически, избавляя вас от этой умственной нагрузки и позволяя сосредоточиться на разработке функций.
До появления React Compiler
Без компилятора вам нужно вручную мемоизировать компоненты и значения, чтобы оптимизировать повторные рендеры:
import { useMemo, useCallback, memo } from 'react';
const ExpensiveComponent = memo(function ExpensiveComponent({ data, onClick }) {
const processedData = useMemo(() => {
return expensiveProcessing(data);
}, [data]);
const handleClick = useCallback((item) => {
onClick(item.id);
}, [onClick]);
return (
<div>
{processedData.map(item => (
<Item key={item.id} onClick={() => handleClick(item)} />
))}
</div>
);
}); Примечание
В этой ручной мемоизации есть неочевидная ошибка, из-за которой она не работает:
<Item key={item.id} onClick={() => handleClick(item)} />
Несмотря на то что handleClick обёрнут в useCallback, стрелочная функция () => handleClick(item) при каждом рендере компонента создаёт новую функцию. Это означает, что Item всегда будет получать новый проп onClick, нарушая мемоизацию.
React Compiler умеет правильно оптимизировать этот код как со стрелочной функцией, так и без неё, обеспечивая повторный рендер Item только при изменении props.onClick.
После появления React Compiler
С React Compiler вы пишете тот же код, но без ручной мемоизации:
function ExpensiveComponent({ data, onClick }) {
const processedData = expensiveProcessing(data);
const handleClick = (item) => {
onClick(item.id);
};
return (
<div>
{processedData.map(item => (
<Item key={item.id} onClick={() => handleClick(item)} />
))}
</div>
);
} Посмотрите этот пример в React Compiler Playground
React Compiler автоматически применяет оптимальную мемоизацию, обеспечивая повторный рендер приложения только при необходимости.
Подробнее
Какую мемоизацию добавляет React Compiler?
Автоматическая мемоизация React Compiler в первую очередь направлена на повышение производительности при обновлении (повторном рендере уже существующих компонентов), поэтому она охватывает два сценария:
-
Пропуск каскадного повторного рендера компонентов
- Повторный рендер
<Parent />приводит к повторному рендеру множества компонентов в его дереве компонентов, хотя изменился только<Parent />
- Повторный рендер
-
Пропуск дорогостоящих вычислений вне React
- Например, вызов
expensivelyProcessAReallyLargeArrayOfObjects()внутри компонента или хука, которому нужны эти данные
- Например, вызов
Оптимизация повторных рендеров
React позволяет описывать пользовательский интерфейс как функцию от текущего состояния (точнее, от пропсов, состояния и контекста). В текущей реализации при изменении состояния компонента React повторно рендерит этот компонент и всех его дочерних компонентов, если только вы не применили какую-либо форму ручной мемоизации с помощью useMemo(), useCallback() или React.memo(). Например, в следующем примере <MessageButton> будет повторно рендериться при каждом изменении состояния <FriendList>:
function FriendList({ friends }) {
const onlineCount = useFriendOnlineCount();
if (friends.length === 0) {
return <NoFriends />;
}
return (
<div>
<span>{onlineCount} online</span>
{friends.map((friend) => (
<FriendListCard key={friend.id} friend={friend} />
))}
<MessageButton />
</div>
);
}
Посмотрите этот пример в React Compiler Playground
React Compiler автоматически применяет эквивалент ручной мемоизации, благодаря чему при изменении состояния повторно рендерятся только нужные части приложения. Иногда это называют «мелкозернистой реактивностью». В приведённом выше примере React Compiler определяет, что возвращаемое значение <FriendListCard /> можно использовать повторно даже при изменении friends, и может избежать как повторного создания этого JSX, так и повторного рендера <MessageButton> при изменении счётчика.
Дорогостоящие вычисления тоже мемоизируются
React Compiler также может автоматически мемоизировать дорогостоящие вычисления, выполняемые во время рендеринга:
// **Not** memoized by React Compiler, since this is not a component or hook
function expensivelyProcessAReallyLargeArrayOfObjects() { /* ... */ }
// Memoized by React Compiler since this is a component
function TableContainer({ items }) {
// This function call would be memoized:
const data = expensivelyProcessAReallyLargeArrayOfObjects(items);
// ...
}
Посмотрите этот пример в React Compiler Playground
Однако, если 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, где можно найти дополнительную информацию и обсуждения компилятора.
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/learn/react-compiler/introduction