Skip to content

Commit 9932845

Browse files
authored
Concurrent Mode Documentation (#2461)
1 parent 6de2fdf commit 9932845

File tree

8 files changed

+2035
-2
lines changed

8 files changed

+2035
-2
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
id: concurrent-mode-adoption
3+
title: Adopting Concurrent More (Experimental)
4+
permalink: docs/concurrent-mode-adoption.html
5+
prev: concurrent-mode-patterns.html
6+
next: concurrent-mode-reference.html
7+
---
8+
9+
>Caution:
10+
>
11+
>This page describes **experimental features that are not yet available in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React.
12+
>
13+
>This documentation is aimed at early adopters and people who are curious. If you're new to React, don't worry about these features -- you don't need to learn them right now.
14+
15+
- [Installation](#installation)
16+
- [Who Is This Experimental Release For?](#who-is-this-experimental-release-for)
17+
- [Enabling Concurrent Mode](#enabling-concurrent-mode)
18+
- [What to Expect](#what-to-expect)
19+
- [Migration Step: Blocking Mode](#migration-step-blocking-mode)
20+
- [Why So Many Modes?](#why-so-many-modes)
21+
- [Feature Comparison](#feature-comparison)
22+
23+
## Installation {#installation}
24+
25+
Concurrent Mode is only available in the [experimental builds](/blog/2019/10/22/react-release-channels.html#experimental-channel) of React. To install them, run:
26+
27+
```
28+
npm install react@experimental react-dom@experimental
29+
```
30+
31+
**There are no semantic versioning guarantees for the experimental builds.**
32+
APIs may be added, changed, or removed with any `@experimental` release.
33+
34+
**Experimental releases will have frequent breaking changes.**
35+
36+
You can try these builds on personal projects or in a branch, but we don't recommend running them in production. At Facebook, we *do* run them in production, but that's because we're also there to fix bugs when something breaks. You've been warned!
37+
38+
### Who Is This Experimental Release For? {#who-is-this-experimental-release-for}
39+
40+
This release is primarily aimed at early adopters, library authors, and curious people.
41+
42+
We're using this code in production (and it works for us) but there are still some bugs, missing features, and gaps in the documentation. We'd like to hear more about what breaks in Concurrent Mode so we can better prepare it for an official stable release in the future.
43+
44+
### Enabling Concurrent Mode {#enabling-concurrent-mode}
45+
46+
Normally, when we add features to React, you can start using them immediately. Fragments, Context, and even Hooks are examples of such features. You can use in new code without making any changes to the existing code.
47+
48+
Concurrent Mode is different. It introduces semantic changes to how React works. Otherwise, the [new features](/docs/concurrent-mode-patterns.html) enabled by it *wouldn't be possible*. This is why they're grouped into a new "mode" rather than released one by one in isolation.
49+
50+
You can't opt into Concurrent Mode on a per-subtree basis. Instead, to opt in, you have to do it in the place where today you call `ReactDOM.render()`.
51+
52+
**This will enable Concurrent Mode for the whole `<App />` tree:**
53+
54+
```js
55+
import ReactDOM from 'react-dom';
56+
57+
// If you previously had:
58+
//
59+
// ReactDOM.render(<App />, document.getElementById('root'));
60+
//
61+
// You can opt into Concurrent Mode by writing:
62+
63+
ReactDOM.createRoot(
64+
document.getElementById('root')
65+
).render(<App />);
66+
```
67+
68+
>Note:
69+
>
70+
>Concurrent Mode APIs such as `createRoot` only exist in the experimental builds of React.
71+
72+
In Concurrent Mode, the lifecycle methods [previously marked](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html) as "unsafe" actually *are* unsafe, and lead to bugs even more than in today's React. We don't recommend trying Concurrent Mode until your app is [Strict Mode](https://reactjs.org/docs/strict-mode.html)-compatible.
73+
74+
## What to Expect {#what-to-expect}
75+
76+
If you have a large existing app, or if your app depends on a lot of third-party packages, please don't expect that you can use the Concurrent Mode immediately. **For example, at Facebook we are using Concurrent Mode for the new website, but we're not planning to enable it on the old website.** This is because our old website still uses unsafe lifecycle methods in the product code, incompatible third-party libraries, and patterns that don't work well with the Concurrent Mode.
77+
78+
In our experience, code that uses idiomatic React patterns and doesn't rely on external state management solutions is the easiest to get running in the Concurrent Mode. We will describe common problems we've seen and the solutions to them separately in the coming weeks.
79+
80+
### Migration Step: Blocking Mode {#migration-step-blocking-mode}
81+
82+
For older codebases, Concurrent Mode might be a step too far. This is why we also provide a new "Blocking Mode" in the experimental React builds. You can try it by substituting `createRoot` with `createBlockingRoot`. It only offers a *small subset* of the Concurrent Mode features, but it is closer to how React works today and can serve as a migration step.
83+
84+
To recap:
85+
86+
* **Legacy Mode:** `ReactDOM.render(<App />, rootNode)`. This is what React apps use today. There are no plans to remove the legacy mode in the observable future — but it won't be able to support these new features.
87+
* **Blocking Mode:** `ReactDOM.createBlockingRoot(rootNode).render(<App />)`. It is currently experimental. It is intended as a first migration step for apps that want to get a subset of Concurrent Mode features.
88+
* **Concurrent Mode:** `ReactDOM.createRoot(rootNode).render(<App />)`. It is currently experimental. In the future, after it stabilizes, we intend to make it the default React mode. This mode enables *all* the new features.
89+
90+
### Why So Many Modes? {#why-so-many-modes}
91+
92+
We think it is better to offer a [gradual migration strategy](/docs/faq-versioning.html#commitment-to-stability) than to make huge breaking changes — or to let React stagnate into irrelevance.
93+
94+
In practice, we expect that most apps using Legacy Mode today should be able to migrate at least to the Blocking Mode (if not Concurrent Mode). This fragmentation can be annoying for libraries that aim to support all Modes in the short term. However, gradually moving the ecosystem away from the Legacy Mode will also *solve* problems that affect major libraries in the React ecosystem, such as [confusing Suspense behavior when reading layout](https://github.com/facebook/react/issues/14536) and [lack of consistent batching guarantees](https://github.com/facebook/react/issues/15080). There's a number of bugs that can't be fixed in Legacy Mode without changing semantics, but don't exist in Blocking and Concurrent Modes.
95+
96+
You can think of the Blocking Mode as of a "gracefully degraded" version of the Concurrent Mode. **As a result, in longer term we should be able to converge and stop thinking about different Modes altogether.** But for now, Modes are an important migration strategy. They let everyone decide when a migration is worth it, and upgrade at their own pace.
97+
98+
### Feature Comparison {#feature-comparison}
99+
100+
<style>
101+
#feature-table table { border-collapse: collapse; }
102+
#feature-table th { padding-right: 30px; }
103+
#feature-table tr { border-bottom: 1px solid #eee; }
104+
</style>
105+
106+
<div id="feature-table">
107+
108+
| |Legacy Mode |Blocking Mode |Concurrent Mode |
109+
|--- |--- |--- |--- |
110+
|String Refs ||🚫** |🚫** |
111+
|Legacy Context ||🚫** |🚫** |
112+
|findDOMNode ||🚫** |🚫** |
113+
|Suspense ||||
114+
|SuspenseList |🚫 |||
115+
|Suspense SSR + Hydration |🚫 |||
116+
|Progressive Hydration |🚫 |||
117+
|Selective Hydration |🚫 |🚫 ||
118+
|Cooperative Multitasking |🚫 |🚫 ||
119+
|Automatic batching of multiple setStates    |🚫* |||
120+
|Priority-based Rendering |🚫 |🚫 ||
121+
|Interruptible Prerendering |🚫 |🚫 ||
122+
|useTransition |🚫 |🚫 ||
123+
|useDeferredValue |🚫 |🚫 ||
124+
|Suspense Reveal "Train" |🚫 |🚫 ||
125+
126+
</div>
127+
128+
\*: Legacy mode has automatic batching in React-managed events but it's limited to one browser task. Non-React events must opt-in using `unstable_batchedUpdates`. In Blocking Mode and Concurrent Mode, all `setState`s are batched by default.
129+
130+
\*\*: Warns in development.

content/docs/concurrent-mode-intro.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
id: concurrent-mode-intro
3+
title: Introducing Concurrent Mode (Experimental)
4+
permalink: docs/concurrent-mode-intro.html
5+
next: concurrent-mode-suspense.html
6+
---
7+
8+
>Caution:
9+
>
10+
>This page describes **experimental features that are [not yet available](/docs/concurrent-mode-adoption.html) in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React.
11+
>
12+
>This documentation is aimed at early adopters and people who are curious. If you're new to React, don't worry about these features -- you don't need to learn them right now.
13+
14+
This page provides a theoretical overview of Concurrent Mode. **For a more practical introduction, you might want to check out the next sections:**
15+
16+
* [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html) describes a new mechanism for fetching data in React components.
17+
* [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html) shows some UI patterns made possible by Concurrent Mode and Suspense.
18+
* [Adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) explains how you can try Concurrent Mode in your project.
19+
* [Concurrent Mode API Reference](/docs/concurrent-mode-reference.html) documents the new APIs available in experimental builds.
20+
21+
## What Is Concurrent Mode? {#what-is-concurrent-mode}
22+
23+
Concurrent Mode is a set of new features that help React apps stay responsive and gracefully adjust to the user's device capabilities and network speed.
24+
25+
These features are still experimental and are subject to change. They are not yet a part of a stable React release, but you can try them in an experimental build.
26+
27+
## Blocking vs Interruptible Rendering {#blocking-vs-interruptible-rendering}
28+
29+
**To explain Concurrent Mode, we'll use version control as a metaphor.** If you work on a team, you probably use a version control system like Git and work on branches. When a branch is ready, you can merge your work into master so that other people can pull it.
30+
31+
Before version control existed, the development workflow was very different. There was no concept of branches. If you wanted to edit some files, you had to tell everyone not to touch those files until you've finished your work. You couldn't even start working on them concurrently with that person — you were literally *blocked* by them.
32+
33+
This illustrates how UI libraries, including React, typically work today. Once they start rendering an update, including creating new DOM nodes and running the code inside components, they can't interrupt this work. We'll call this approach "blocking rendering".
34+
35+
In Concurrent Mode, rendering is not blocking. It is interruptible. This improves the user experience. It also unlocks new features that weren't possible before. Before we look at concrete examples in the [next](/docs/concurrent-mode-suspense.html) [chapters](/docs/concurrent-mode-patterns.html), we'll do a high-level overview of new features.
36+
37+
### Interruptible Rendering {#interruptible-rendering}
38+
39+
Consider a filterable product list. Have you ever typed into a list filter and felt that it stutters on every key press? Some of the work to update the product list might be unavoidable, such as creating new DOM nodes or the browser performing layout. However, *when* and *how* we perform that work plays a big role.
40+
41+
A common way to work around the stutter is to "debounce" the input. When debouncing, we only update the list *after* the user stops typing. However, it can be frustrating that the UI doesn't update while we're typing. As an alternative, we could "throttle" the input, and update the list with a certain maximum frequency. But then on lower-powered devices we'd still end up with stutter. Both debouncing and throttling create a suboptimal user experience.
42+
43+
The reason for the stutter is simple: once rendering begins, it can't be interrupted. So the browser can't update the text input right after the key press. No matter how good a UI library (such as React) might look on a benchmark, if it uses blocking rendering, a certain amount of work in your components will always cause stutter. And, often, there is no easy fix.
44+
45+
**Concurrent Mode fixes this fundamental limitation by making rendering interruptible.** This means when the user presses another key, React doesn't need to block the browser from updating the text input. Instead, it can let the browser paint an update to the input, and then continue rendering the updated list *in memory*. When the rendering is finished, React updates the DOM, and changes are reflected on the screen.
46+
47+
Conceptually, you can think of this as React preparing every update "on a branch". Just like you can abandon work in branches or switch between them, React in Concurrent Mode can interrupt an ongoing update to do something more important, and then come back to what it was doing earlier. This technique might also remind you of [double buffering](https://wiki.osdev.org/Double_Buffering) in video games.
48+
49+
Concurrent Mode techniques reduce the need for debouncing and throttling in UI. Because rendering is interruptible, React doesn't need to artificially *delay* work to avoid stutter. It can start rendering right away, but interrupt this work when needed to keep the app responsive.
50+
51+
### Intentional Loading Sequences {#intentional-loading-sequences}
52+
53+
We've said before that Concurrent Mode is like React working "on a branch". Branches are useful not only for short-term fixes, but also for long-running features. Sometimes you might work on a feature, but it could take weeks before it's in a "good enough state" to merge into master. This side of our version control metaphor applies to rendering too.
54+
55+
Imagine we're navigating between two screens in an app. Sometimes, we might not have enough code and data loaded to show a "good enough" loading state to the user on the new screen. Transitioning to an empty screen or a large spinner can be a jarring experience. However, it's also common that the necessary code and data doesn't take too long to fetch. **Wouldn't it be nicer if React could stay on the old screen for a little longer, and "skip" the "bad loading state" before showing the new screen?**
56+
57+
While this is possible today, it can be difficult to orchestrate. In Concurrent Mode, this feature is built-in. React starts preparing the new screen in memory first — or, as our metaphor goes, "on a different branch". So React can wait before updating the DOM so that more content can load. In Concurrent Mode, we can tell React to keep showing the old screen, fully interactive, with an inline loading indicator. And when the new screen is ready, React can take us to it.
58+
59+
### Concurrency {#concurrency}
60+
61+
Let's recap the two examples above and see how Concurrent Mode unifies them. **In Concurrent Mode, React can work on several state updates *concurrently*** — just like branches let different team members work independently:
62+
63+
* For CPU-bound updates (such as creating DOM nodes and running component code), concurrency means that a more urgent update can "interrupt" rendering that has already started.
64+
* For IO-bound updates (such as fetching code or data from the network), concurrency means that React can start rendering in memory even before all the data arrives, and skip showing jarring empty loading states.
65+
66+
Importantly, the way you *use* React is the same. Concepts like components, props, and state fundamentally work the same way. When you want to update the screen, you set the state.
67+
68+
React uses a heuristic to decide how "urgent" an update is, and lets you adjust it with a few lines of code so that you can achieve the desired user experience for every interaction.
69+
70+
## Putting Research into Production {#putting-research-into-production}
71+
72+
There is a common theme around Concurrent Mode features. **Its mission is to help integrate the findings from the Human-Computer Interaction research into real UIs.**
73+
74+
For example, research shows that displaing too many intermediate loading states when transitioning between screens makes a transition feel *slower*. This is why Concurrent Mode shows new loading states on a fixed "schedule" to avoid jarring and too frequent updates.
75+
76+
Similarly, we know from research that interactions like hover and text input need to be handled within a very short period of time, while clicks and page transitions can wait a little longer without feeling laggy. The different "priorities" that Concurrent Mode uses internally roughly correspond to the interaction categories in the human perception research.
77+
78+
Teams with a strong focus on user experience sometimes solve similar problems with one-off solutions. However, those solutions rarely survive for a long time, as they're hard to maintain. With Concurrent Mode, our goal is to bake the UI research findings into the abstraction itself, and provide idiomatic ways to use them. As a UI library, React is well-positioned to do that.
79+
80+
## Next Steps {#next-steps}
81+
82+
Now you know what Concurrent Mode is all about!
83+
84+
On the next pages, you'll learn more details about specific topics:
85+
86+
* [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html) describes a new mechanism for fetching data in React components.
87+
* [Concurrent UI Patterns](/docs/concurrent-mode-patterns.html) shows some UI patterns made possible by Concurrent Mode and Suspense.
88+
* [Adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) explains how you can try Concurrent Mode in your project.
89+
* [Concurrent Mode API Reference](/docs/concurrent-mode-reference.html) documents the new APIs available in experimental builds.

0 commit comments

Comments
 (0)