The article includes the following:

  1. Here is a brief review of React’s iterative history from 16 to 21 years

  2. Why is React so obsessed with new Concurrent Mode features

  3. Why is it difficult to upgrade current community projects/libraries to Concurrent Mode

Iteration History Review

The React Core Team began to transform the React Core module Reconciler (where the Diff algorithm is executed) in 2016.

After more than a year of work, it was transformed from a recursive implementation of processes that cannot be interrupted, known as Stack Reconciler, to a traversal implementation of processes that can be interrupted, known as Fiber Reconciler.

Since then, a mechanism for prioritizing tasks has been put in place, based on Fiber Reconciler. The general principles are as follows:

Different interactions (user click interaction/request data/user drag…) Triggered status updates (such as a call to this.setState) have different priorities and correspond to a timestamp variable expirationTime within the source code.

React schedules these updates based on the size of the expirationTime. As a result, updates triggered by user interactions are given higher priority than updates triggered by requests.

The high priority means that the impact of the update on the DOM becomes apparent to users more quickly.

After this, the React Core Team found that the scheduling algorithm based on expirationTime can satisfy the overall priority scheduling of fiber trees, but it is not flexible enough (for example, it cannot satisfy priority scheduling of partial Fiber trees (e.g. Suspense)).

See this article: Heuristic update algorithms

So last year Andrew Clark of the React Core Team reconstructed the expirationTime model into a Lane model with 32-bit bits representing priorities.

PR see Initial Lanes Implementation #18796

If you’re a heavy user of React, you might say:

  • The Context API refactoring

  • Hooks

But judging from what we’ve talked about above, there was a lot of refactoring going on at the bottom of React from 2016 to 21.

Some people ask: With all the refactoring, how can React developers feel nothing?

Yes, even though the current stable version of React already supports time slicing at the bottom and a smarter update merge mechanism (batchedUpdates).

But there are a number of binding codes in React that make the new framework behave in Stack Reconciler with the old one.

The React Core Team’s obsession

Just as business developers are burdened with OKR, React Core Team members are also burdened with OKR.

In the React Christmas special, Rachel Nabors of the React Core Team writes:

Just because you’re not productive doesn’t mean you’re worthless.

As a library for the view layer, React is about as good as it gets without stretching the imagination.

React adopted the concepts of coroutines and concurrency from the OPERATING system. In React, the concepts of functional programming landed on Hooks.

React where to go?

The answer, according to Sebastian Markbage, the soul of React, author of Hooks and a member of TC39:

Develop backwards and towards the BFF layer

To put it simply:

In the SSR field, the current implementation scheme is still relatively rough:

  1. Component compiled into template strings on the server side (dehydration)

  2. Front-end render template string

  3. Complete the component’s interactivity (waterflooding) with the rest of the rendering

Such SSR schemes are not fine-grained enough. If Fiber Reconciler can control the granularity of time slices at the component level, why not SSR at the component level?

To achieve this goal, we need at least support:

  • A stream protocol for the React component (distinct from the string template)

  • The front end can accurately control the component’s state (loading/failed/succeeded), which is the Suspense feature

Suspense features depend on the time slice characteristics of Concurrent Mode.

Sebastian Markbage’s lofty ideal (OKR) is a pie in the sky without the community’s large library of Concurrent modes, making time slicing the default configuration.

So it’s imperative that the community catch up with the React upgrade as soon as possible.

upgradeConcurrent ModeThe difficulties of

The current React ecosystem logic is based on the following React workflow:

Status update --> Render --> View renderCopy the code

If the React runtime flow becomes:

Status update --> View render or status update --> Render --> Re-status update --> Render --> View renderCopy the code

What happens?

An example of a phenomenon called tearing can occur:

Let’s say we have a variable externalSource with an initial value of 1.

After 1000ms, externalSource will change to 2.

let externalSource = 1;

setTimeout(() = > {
    externalSource = 2;
}, 1000)
Copy the code

We have component A that renders the DOM depending on the value of externalSource:

function A() {
  return <p>{externalSource}</p>;
}
Copy the code

In the current version of React, when we use component A in different parts of the component tree in our application, will the DOM be

1

in some places and

2

in others?

The answer is: no.

The React process is synchronized:

Status update --> Render --> View renderCopy the code

The setTimeout that changes externalSource to 2 will be executed after the process’s corresponding task (macro task) has finished executing.

But when switching to Concurrent Mode:

Status update --> Render --> View renderCopy the code

When Render pauses and the browser gains JS thread control, it executes a setTimeout that changes externalSource to 2.

In this way, different A components may render different numbers in the P tag.

This phenomenon, which occurs when the React process changes and the status of a dependency on an external resource differs from the view, is called tearing.

Change externalSource force here, may come from the various task (IO, setTimeout…).

There is currently a proposal to address external resource state synchronization useMutableSource

The will-this-react-global-state-work-in-concurrent-mode library tests whether the mainstream status management library will cause tearing

Hard baby steps

In order for developers to upgrade to Concurrent Mode gradually and painlessly, the React Core Team has been working on:

  • Provide StrictMode components to regulate developer behavior

  • Mark componentWilXXX as unSAFt_

  • Provide progressive upgrade paths (from Legacy mode to Blocking mode to Concurrent mode)

Apparently, the React Core Team felt the community was still too slow to upgrade.

Recently, a new PR has been added: Make time-slicing opt-in

As mentioned in this PR: In the next major release, a full Concurrent Mode will be implemented, but this Concurrent Mode will have time slicing disabled by default.

Poor direct propaganda developers: everybody big ye, beg you quick upgrade bar, OKR pointed to him 😭

This sad, eager and expectative mood directly led Ricky, who submitted this PR, to gradually sand sculpture (dog head to save his life) :

React’s OS dream has a long way to go