1. The introduction

The article is scheduling-in-React, which simply means the react scheduling system in order to get a smoother user experience.

After all, the end of the front-end is experience optimization, and the core value of the front-end to the user lies in this.

Summary of 2.

The article starts with Dan’s Demo in JSConf:

This is a performance test Demo, and as the number of characters in the input box increases, the amount of data shown in the chart below increases dramatically. The results in Synchronous and Debmentioning modes are not satisfactory, and only the Concurrent mode looks smooth.

So why does a normal Demo suck?

This is where the browser Event Loop rule comes in.

JS is single-threaded, the browser can only do one thing at a time, and the visually recognizable refresh rate is around 60FPS, which means we need to do three things in the Demo in less than 16ms: respond to user input, animate, and render Dom.

However, almost all current frameworks use synchronous rendering mode, which means that if a render function takes longer than 16ms, it will inevitably stall.

To sum up, there are two main problems:

  1. Long running tasks cause the page to stall, and we need to make sure that all tasks are completed within milliseconds to keep the page running smoothly.
  2. Different tasks have different priorities. For example, tasks responding to user input have higher priorities than animations. This is easy to understand.

React Scheduling mechanism

To solve this problem, React16 addresses the problem from both a Concurrent and Scheduler perspective:

  • Concurrent: transforms synchronous rendering into asynchronous rendering that can be detachable for multiple steps, allowing for multiple iterations of rendering code over 16ms.
  • Scheduler: a scheduling system that supports different rendering priorities and schedules Concurrent. Of course, the scheduling system will constantly increase the priority of low-priority tasks, so there will not be a situation where low-priority tasks are not always executed.

To ensure that there is no sense of blocking, the scheduling system keeps a list of all callback functions that need to be executed between each browser render time shard and executes them as much as possible, holding any that are not executed until the next shard.

The official API for Concurrent will be released in Q2 2019 and can now be called using the

API:

ReactDOM.render(
  <React.unstable_ConcurrentMode>
    <App />
  </React.unstable_ConcurrentMode>,
  rootElement
);
Copy the code

This is not enough because we have not yet declared the priority of each function. We can use the NPM I Scheduler package to declare the priority of a function:

import { unstable_next } from "scheduler";

function SearchBox(props) {
  const [inputValue, setInputValue] = React.useState();

  function handleChange(event) {
    const value = event.target.value;

    setInputValue(value);
    unstable_next(function() {
      props.onChange(value);
      sendAnalyticsNotification(value);
    });
  }

  return <input type="text" value={inputValue} onChange={handleChange} />;
}
Copy the code

The code under unstable_next() is Normal, so the result is:

  1. ifprops.onChange(value)If the execution can be completed within 16ms, it is not usedunstable_nextNo difference.
  2. ifprops.onChange(value)If it takes too long to execute, maybe this function will be executed in the next few Render sessions without blocking subsequent high-priority tasks.

Scheduling limitations

There are also two problems with the scheduling system.

  1. Only one scheduling system can exist. If two scheduling systems exist at the same time, the scheduling correctness cannot be guaranteed.
  2. The scheduling system has limited capabilities. It can only schedule within the capabilities provided by the browser, and cannot affect, for example, the Html rendering and recycling cycle.

To address this issue, Chrome is working with React, Polymer, Ember, Google Maps, and the Web Standars Community to create a browser scheduling specification that provides browser-level apis that allow scheduling to control lower-level rendering timing. It also ensures the uniqueness of the scheduler.

3. The intensive reading

For an in-depth analysis of the React scheduling system, read the React Concurrent article, thanks to our team.

To put it simply, a Render usually involves many child nodes, and Fiber architecture can suspend execution during the Render phase, node by node, thus enabling scheduling capabilities.

React scheduling capability limitations

This means that if your React application is currently running smoothly, enabling Concurrent will not improve the performance experience of your application. If your React application is currently stuttering, or in some cases stuttering, Concurrent may be able to save you. Bring about some change.

As mentioned in React Concurrent in Depth, if your application doesn’t have performance issues, don’t expect React scheduling capabilities to help.

This is also to say that if a piece of code logic does not have performance problems, there is no need to use Concurrent optimization because it is not valid. We need to be able to distinguish which logic needs to be optimized and which logic does not.

Try Function Component now

In order to implement React Schedule, it is important to learn how to write components using Function Component mode because:

  1. The Class Component lifecycle concept prevents the React scheduling system from splitting tasks.
  2. The dispatch system might be rightcomponentWillMountRepeated calls make it easy to write bad code in Class Component mode.
  3. The Function Component follows a stricter separation of side effects so that Concurrent execution does not cause unintended effects.

React.lazy

Concurrent also ships with the React component dynamic import and load scheme. Normal component loading looks like this:

import OtherComponent from "./OtherComponent";

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}
Copy the code

But if import() is used for dynamic loading, you can use react.lazy to make dynamically imported components used as normal components:

const OtherComponent = React.lazy((a)= > import("./OtherComponent"));

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}
Copy the code

To join Loading, you can use it with Suspense:

import React, { lazy, Suspense } from "react";
const OtherComponent = lazy((a)= > import("./OtherComponent"));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>} ><OtherComponent />
    </Suspense>
  );
}
Copy the code

Like Concurrent, the React.lazy scheme is a performance-beneficial component loading scheme.

Scheduling classification

Scheduling is divided into four levels:

  • Immediate: Executes immediately and has the highest priority.
  • render-blocking: blocks the render priority, similar priorityrequestAnimationFrame. If this priority task cannot be executed, it may cause the UI rendering to be blocked.
  • default: Default priority, common priority. Priority can be understood assetTimeout(0)The priority of.
  • Idle: Tasks that users do not see or care about, such as notifications.

The current proposed API is similar to the following:

function mytask() {... } myQueue = TaskQueue.default("render-blocking")
Copy the code

Create an execution queue and set the priority of the queue.

taskId = myQueue.postTask(myTask, <list of args>);
Copy the code

Submit the queue and get the execution ID of the current queue, which can be used to determine when the queue is finished.

myQueue.cancelTask(taskId);
Copy the code

You can cancel the execution of a function if necessary.

4. To summarize

With Hooks out, are you ready for Concurrent and Suspense?

I want you to think about how these three apis will change front-end development. Welcome to leave a message!

Scheduling in React · Issue #146 · DT-FE /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

special Sponsors

  • DevOps full process platform

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)