Logo

dev-resources.site

for different kinds of informations.

Что делает React Compiler?

Published at
1/15/2025
Categories
react
webdev
Author
jennypollard
Categories
2 categories in total
react
open
webdev
open
Author
12 person written this
jennypollard
open
Что делает React Compiler?

Реакт Компилятор (react compiler) - это инструмент для оптимизации React-приложений. Компилятор включается в работу во время сборки приложения и трансформирует код так, чтобы избежать ненужные ререндеры.

Компилятор анализирует код, составляет его упрощенное представление, находит места, которые можно оптимизировать, трансформирует выбранный код. Реакт Компилятор предполалагет, что код удовлетворяет Правилам Реакта - такой код не сломается от оптимизаций компилятора. Если код не удовлетворяет Правилам, то он будет проигнорирован.

Компилятор применяет к коду, как минимум, две трансформации: мемоизирует результат рендера и результат вычисления выражений внутри компонентов.

Мемоизация результата рендера

Результатом рендера я называю выражение, которое возвращается из компонента: return <div>{items}</div>, в этом примере <div>{items}</div> - результат рендера. Результат рендера зависит от пропсов и промежуточных значений, вычисленных внутри компонента. Назовем эти значения зависимостями выражения. Когда результат рендера остается постоянным при одних и тех же зависимостях, вычисление выражения можно пропустить. Для этого Реакт Компилятор вставит код, запоминающий последний результат вычисления:

  1. Если выражение вычисляется первый раз, то вычисляет выражение, сохраняет результат в кэш, сохраняет зависимости в кэш.
  2. Если выражение вычисляется повторно, сравнивает новые значения зависимостей с сохраненными в кэше:
  3. Если они равны, использует закэшированное значение выражения.
  4. Если они разные, вычисляет выражение с новыми зависимостями, сохраняет результат вычисления и зависимости в кэш.

Такой компонент:

function Div({ item, other }) {
  return <div data-x={other}>{item}</div>;
}
Enter fullscreen mode Exit fullscreen mode

Реакт Компилятор преобразует вот так:

import { c as _c } from "react/compiler-runtime";
function Div(t0) {
  const $ = _c(3);
  const { item, other } = t0;
  let t1;
  if ($[0] !== item || $[1] !== other) {
    t1 = <div data-x={other}>{item}</div>;
    $[0] = item;
    $[1] = other;
    $[2] = t1;
  } else {
    t1 = $[2];
  }
  return t1;
}
Enter fullscreen mode Exit fullscreen mode

Можно догадаться, что в строке const $ = _c(3) Реакт Компилятор создает локальный кэш на 3 элемента. В действительности, c из react/compiler-runtime вызывает внутри себя React.useMemo.

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

Код в примере выше аналогичен оборачиванию компонента в memo.

Мемоизация выражений

В примере выше, jsx-выражение зависило только от пропсов компонента. Часто в компонентах вычисляются промежуточные значения, которые подставляются в jsx-выражения. Эти промежуточные значения также могут быть мемоизированы. Для этого Реакт Компилятор определит зависимости выражения и вставит код для кэширования всего выражения на основе этих зависимостей.

Рассмотрим пример, в котором внутри компонента происходит вычисление:

export default function App(props) {

  const name = props.fullname.split(' ')[0];

  return <main>
    {name}
  </main>;
}
Enter fullscreen mode Exit fullscreen mode

В этом примере <main>{name}</main> - это jsx-выражение, его зависимость - переменная name, которая в свою очередь вычисляется выше выражением props.fullname.split(' ')[0]. Выражение props.fullname.split(' ')[0] зависит только от пропсы fullname.
Реакт Компилятор преобразует этот компонент следующим образом:

import { c as _c } from "react/compiler-runtime";
export default function App(props) {
  const $ = _c(4);
  let t0;
  if ($[0] !== props.fullname) {
    t0 = props.fullname.split(" ");
    $[0] = props.fullname;
    $[1] = t0;
  } else {
    t0 = $[1];
  }
  const name = t0[0];
  let t1;
  if ($[2] !== name) {
    t1 = <main>{name}</main>;
    $[2] = name;
    $[3] = t1;
  } else {
    t1 = $[3];
  }
  return t1;
}
Enter fullscreen mode Exit fullscreen mode

Реакт Компилятор закэширует props.fullname и результат вычисления name. Если пропса fullname поменяется, выражение будет вычислено и закэшировано еще раз. Этот код аналогичен оборачиванию вычисления name в useMemo в исходном компоненте:

import {useMemo} from 'react';

export default function App(props) {

  const name = useMemo(() => props.fullname.split(' ')[0], [props.fullname]);

  return <main>
    {name}
  </main>;
}
Enter fullscreen mode Exit fullscreen mode

Включение Реакт Компилятора может не принести ощутимой пользы в проекте, в котором осознанно используются useMemo и memo.

webdev Article's
30 articles in total
Web development involves creating websites and web applications, combining coding, design, and user experience to build functional online platforms.
Favicon
7 Developer Tools That Will Boost Your Workflow in 2025
Favicon
Lessons from A Philosophy of Software Design
Favicon
Can I build & market a SaaS app to $100 in 1 month?
Favicon
Learning HTML is the best investment I ever did
Favicon
Creating a live HTML, CSS and JS displayer
Favicon
How to scrape Crunchbase using Python in 2024 (Easy Guide)
Favicon
🕒 What’s your most productive time of the day?
Favicon
Daily.dev's unethical software design
Favicon
Unique Symbols: How to Use Symbols for Type Safety
Favicon
How To Build Beautiful Terminal UIs (TUIs) in JavaScript 2: forms!
Favicon
[Boost]
Favicon
Cómo Iniciar y Crecer como Desarrollador Frontend en 2025
Favicon
Filling a 10 Million Image Grid with PHP for Internet History
Favicon
Chronicles of Supermarket website
Favicon
Building bun-tastic: A Fast, High-Performance Static Site Server (OSS)
Favicon
Easy development environments with Nix and Nix flakes!
Favicon
My React Journey: Project
Favicon
Boost Your Productivity with Momentum Builder: A Web App to Overcome Procrastination and Track Progress
Favicon
Что делает React Compiler?
Favicon
Day 04: Docker Compose: Managing multi-container applications
Favicon
Setup Shopify GraphQL Admin API Client in Hydrogen
Favicon
The Language Server Protocol - Building DBChat (Part 5)
Favicon
How to Use JavaScript to Reduce HTML Code: A Simple Example
Favicon
From Bootcamp to Senior Engineer: Growing, Learning, and Feeling Green
Favicon
📝✨ClearText
Favicon
Habit Tracker: A Web Application to Track Your Daily Habits
Favicon
Impostor syndrome website: Copilot 1-Day Build Challenge
Favicon
Easy Discount Calculation: Tax, Fees & Discount Percentage Explained
Favicon
Example of using Late Static Binding in PHP.
Favicon
Top 5 Python Scripts to Automate Your Daily Tasks: Boost Productivity with Automation

Featured ones: