17
头图

Hello everyone, I'm Casson.

Maybe many friends have not used Suspense in the project, but Suspense is a very important part of the future development of React .

This article will explain the significance of Suspense to React .

Welcome to join human high-quality front-end framework group , with flying

React's iterative process

The main features of React from v16 to v18 have undergone three major changes:

  • v16: Async Mode
  • v17: Concurrent Mode
  • v18: Concurrent Render (concurrent update)

To understand the meaning of these three changes, you need to first understand a very confusing concept in React - render (rendering).

The ClassComponent function of render is called render when executed:

class App extends Component {
  render() {
    // ...这是render函数
  }
}

The process of rendering the result of render to the page is called commit .

The purpose of Async Mode is to make render asynchronous and interruptible.

The purpose of Concurrent Mode is to make commit in the user's perception.

Since Concurrent Mode contains breaking change , v18 proposes Concurrent Render to reduce the cost of developer migration.

So what does that commits are concurrent in the user's perception?

The meaning of "concurrency"

Speaking concurrent with , we have to mention Suspense . Consider the following code:

const App = () => {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    setInterval(() => {
      setCount(count => count + 1);
    }, 1000);
  }, []);
  
  return (
    <>
      <Suspense fallback={<div>loading...</div>}>
        <Sub count={count} />
      </Suspense>
      <div>count is {count}</div>
    </>
  );
};

in:

  • An update is triggered every second that updates the status count to count => count + 1
  • An asynchronous request will be initiated in Sub . Before the request is returned, Sub wrapped in Suspense will render fallback

Assuming that the request returns after three seconds, ideally, the pages before and after the request is initiated will be displayed as follows:

// Sub内请求发起前
<div class=“sub”>I am sub, count is 0</div>
<div>count is 0</div>

// Sub内请求发起第1秒
<div>loading...</div>
<div>count is 1</div>

// Sub内请求发起第2秒
<div>loading...</div>
<div>count is 2</div>

// Sub内请求发起第3秒
<div>loading...</div>
<div>count is 3</div>

// Sub内请求成功后
<div class=“sub”>I am sub, request success, count is 4</div>
<div>count is 4</div>

From the user's point of view, there are two tasks on the page executing concurrently on at :

  1. The task of requesting Sub (observe the change of the first div )
  2. Change the task of count (observe the change of the second div )

The multi-tasking concurrent execution of in the Suspense page brought by is the meaning of Concurrent (concurrency) in React .

In fact, when Async Mode , Suspense has been supported. But the above code behaves as follows in the page of Async Mode :

// Sub内请求发起前
<div class=“sub”>I am sub, count is 0</div>
<div>count is 0</div>

// Sub内请求发起第1秒
<div>loading...</div>
<div>count is 0</div>

// Sub内请求发起第2秒
<div>loading...</div>
<div>count is 0</div>

// Sub内请求发起第3秒
<div>loading...</div>
<div>count is 0</div>

// Sub内请求成功后
<div class=“sub”>I am sub, request success, count is 4</div>
<div>count is 4</div>

From the user's perspective, when requests Sub's task to execute, 's task that changes count is frozen.

That's why it's called Async (asynchronous) instead of Concurrent (concurrent).

Meaning of Suspense

It can be seen that for Concurrent , Suspense is an essential part.

It can be considered that the role of Suspense is that divides the part of the page that needs to be rendered concurrently .

For example, in the above example, the task Suspense that requests Sub from and the task changes the count of are separated by 06201f1d34463e, and are executed visually concurrently.

When the meaning of Suspense is clarified, you will find that React is doing next is to continuously expand the scene of Suspense (that is, to include more scenes into the category of concurrent rendering).

For example, currently existing:

  • React.lazy
  • Asynchronous request transformed by React library provided by fetch
  • useTransition
  • useDeferredvalue

In the future will be added:

  • Server Component
  • Selective Hydration

Summarize

The development process of React is: from synchronous to asynchronous , and then to concurrent .

When is implemented concurrently with , the next development direction will be: expanding the scenarios where can be used concurrently with .

The role of Suspense is divides the part of the page that needs to be rendered concurrently .

This development path has been decided since the birth of React , because architecturally, React is heavily dependent on runtime. In order to optimize performance, concurrently with is the optimal development direction under this architecture.


卡颂
3.1k 声望16.7k 粉丝