Unlocking React Performance: The Power of React Compiler

BY Mark Howell 28 June 20246 MINS READ
article cover

Today in Edworking News we want to talk about Home Blog Understanding React Compiler
React's core architecture calls the functions you give it (i.e., your components) over and over. This fact both contributed to its popularity by simplifying its mental model and created a point of possible performance issues. In general, if your functions do expensive things, then your app will be slow. Performance tuning, therefore, became a pain point for developers, as they had to manually tell React which functions should be re-run and when. The React team has now provided a tool called the React Compiler to automate that manual work performance tuning for developers, by rewriting their code.

What does React Compiler do to your code?

How does it work under-the-hood? Should you use it? Let's dive in. To gain a complete, accurate mental model of React by deep diving into its internals, check out my new course Understanding React where we dig into React's source code. I've found a deep understanding of React's internals greatly helps even developers with years of React experience.

Compilers, Transpilers, and Optimizers

We hear the terms compiler, transpiler, and optimizer thrown about the modern JavaScript ecosystem. What are they?

Transpilation

A transpiler is a program that analyzes your code and outputs functionally equivalent code in a different programming language, or an adjusted version of your code in the same programming language. React developers have been using a transpiler for years to convert JSX to the code that is actually run by the JavaScript engine. JSX is essentially shorthand for building trees of nested function calls, making the developer's life easier.

Compilation and Optimization

So what's the difference between a transpiler and a compiler? Coming from a computer science background, you might think a compiler converts code into machine language. However, "transpilers" are also called "source-to-source compilers". Optimizers are also called "optimizing compilers". Transpilers and optimizers are types of compilers.
Naming things is hard, so there will be disagreements about what constitutes a transpiler, compiler, or optimizer. The important thing to understand is that they are programs that take a text file containing your code, analyze it, and produce a new text file of different but functionally equivalent code. They may make your code better or add abilities by wrapping bits of your code in calls to other people's code.

Abstract Syntax Trees

When we say your code is "analyzed", we mean the text of your code is parsed character-by-character and algorithms are run against it to figure out how to adjust it. The parsing usually results in an abstract syntax tree (AST), a tree of data that represents your code.
For example, let's suppose you have a line in your code:
```jsx
const a = { desc: 'Hi' };
The abstract syntax tree for that line might look something like this:

Image: An Abstract Syntax Tree of a simple JavaScript variable.
The generated data structure describes your code as you wrote it. This mental model is essential when using a transpiler/compiler, as it helps visualize how the tool is working.

React's Core Architecture

React's core architecture is both a source of its popularity and a potential performance issue. When you write JSX, you're actually writing nested function calls that React decides when to call. For instance, in a React app handling a list of items, React builds a tree from all these objects called the Fiber tree.
Each node in the tree is called a Fiber node. React compares two branches of this tree—the "current" state and the "work-in-progress" state—during a process called reconciliation. This system ensures the actual DOM matches the work-in-progress side of the tree.

Memoization

A solution to repeated calls to expensive functions is to cache the results. This process is called memoization. For memoization to work, the function must be "pure", meaning it always returns the same output for the same inputs.

Hook Storage

React stores state on the client's device. For example, when you call `useState` and `useReducer`, React attaches the state to the Fiber tree created from the component.
React also stores the results of expensive functions using useMemo, which stores inputs and outputs in the node that calls `useMemo`. This makes memoization in React essential for keeping apps from becoming slow.

React Compiler: The Automation Hero

React Compiler automates this memoization process, analyzing text of your React code and producing new code ready for JSX transpilation with built-in memoization.
For example, before compilation:
```jsx
function List({ items }) {
const processedItems = processItems(items);
return <ul>{processedItems.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
}
After compilation:
```jsx
function List({ items }) {
const _c = React.useMemo(() => [6], []);
const processedItems = _c[2] ?? (_c[2] = processItems(items));
const children = _c[5] ?? (_c[5] = processedItems.map(item => <li key={item.id}>{item.name}</li>));
return <ul>{children}</ul>;
}
This automatic handling by React Compiler saves developers from manually managing dependencies or memoization.

Trading Processor Cycles for Device Memory

Memoization and caching trade processing for memory, saving on processor cycles but using more device memory. This consideration is crucial if your app handles large amounts of data.

Abstractions and Debugging

Compilation introduces an abstraction layer, making debugging more challenging. However, a solid mental model of the abstraction helps in accurately debugging the code generated from it.

Remember these 3 key ideas for your startup:

  1. Automate Performance Tuning with React Compiler: React Compiler takes the heavy lifting out of manual memoization, helping your app run more efficiently without extra effort on your part.

  2. Understand the Abstractions: Having a deep mental model of React's internals, including React Compiler, can greatly aid in debugging and optimizing your applications.

  3. Balancing Memory and Performance: Be mindful of the trade-off between processing power and memory usage. Good architectural decisions can prevent potential performance bottlenecks and memory issues.
    Edworking is the best and smartest decision for SMEs and startups to be more productive. Edworking is a FREE superapp of productivity that includes all you need for work powered by AI in the same superapp, connecting Task Management, Docs, Chat, Videocall, and File Management. Save money today by not paying for Slack, Trello, Dropbox, Zoom, and Notion.
    Embark on a journey to understand React deeply. Enroll in the Understanding React Course and gain lifetime access to immerse yourself in React's features and streamline your development process.
    For more details, see the original source.

article cover
About the Author: Mark Howell Linkedin

Mark Howell is a talented content writer for Edworking's blog, consistently producing high-quality articles on a daily basis. As a Sales Representative, he brings a unique perspective to his writing, providing valuable insights and actionable advice for readers in the education industry. With a keen eye for detail and a passion for sharing knowledge, Mark is an indispensable member of the Edworking team. His expertise in task management ensures that he is always on top of his assignments and meets strict deadlines. Furthermore, Mark's skills in project management enable him to collaborate effectively with colleagues, contributing to the team's overall success and growth. As a reliable and diligent professional, Mark Howell continues to elevate Edworking's blog and brand with his well-researched and engaging content.

Trendy NewsSee All Articles
Try EdworkingA new way to work from  anywhere, for everyone for Free!
Sign up Now