Expiration Time concept review

The concept of expiration-time has been briefly introduced in the last article, and it is summarized here. As mentioned above, there exists asynchronous expiration-time, and the priority of computing expiration-time for asynchronous tasks is usually low, so asynchronous tasks can be interrupted. To prevent asynchronous tasks from being interrupted, React forces the task to be executed when the Expiration Time of the task has not expired

Types of Expiration Time

React has a variety of expirationTime variables that help React schedule tasks with different priorities in a single-threaded environment

  • root.expirationTime
  • root.nextExpirationTimeToWorkOn
  • root.childExpirationTime
  • root.earliestPendingTime & root.lastestPendingTime
  • root.earliestSuspendedTime & root.lastestSuspendedTime
  • root.lastestPingedTime
  • nextFlushedExpirationTime
  • nextLatestAbsoluteTimeoutMs
  • currentRendererTime
  • currentSchedulerTime

Here expirationTime involves more concepts, and will be slowly supplemented and reviewed in the later dispatch update. This is to be continued

In addition, every node has a expirationTime and a childExpirationTime property that you see in Fiber. All of the above values start with NoWork (0), and there are several possible scenarios:

  • NoWork, indicates that there is no update
  • Sync, which means synchronous execution, not scheduled and not interrupted immediately after creationReactYou need to update
  • asyncThe expiration time calculated in mode, a timestamp asynchronous mode will be scheduled, it may be interrupted, it will be scheduled according to priority, low priority500Ms is the unit of time, if it’s high priority50Ms is the unit of time
  • The targetcontextIn the case

Let’s first look at the logic of calculating Expiration Time, We found in the ReactFiberScheduler source updateContainer create update phase call computeExpirationForFiber method cuts

ExpirationContext

Context is a context with an expiration date. By default, you would like to see a context with an expiration date equal to NoWork. Also in ReactFiberScheduler source code find the following two methods will modify the CONTEXT

  • deferredUpdates
  • syncUpdates

ExpirationContext = expirationContext = expirationContext = expirationContext = expirationContext = expirationContext = expirationContext = expirationContext = expirationContext = expirationContext

function syncUpdates<A.B.C0.D.R> (fn: (A, B, C0, D) => R, a: A, b: B, c: C0, d: D,) :R {
  const previousExpirationContext = expirationContext;
  // The expirationContext context is modified
  expirationContext = Sync;
  try {
    return fn(a, b, c, d);
  } finally{ expirationContext = previousExpirationContext; }}Copy the code

ComputeExpirationForFiber method resolution

The source code and code comments computeExpirationForFiber method

// The current time and Fiber node are passed into the method
function computeExpirationForFiber(currentTime: ExpirationTime, fiber: Fiber) {
  let expirationTime;
  // The expirationContext is set to an expired context.
  / / so expirationContext
  if(expirationContext ! == NoWork) {// Assign a expirationContext directly to expirationTime
    expirationTime = expirationContext;
  } else if (isWorking) { // Check whether the task is updating
    // The logic involved in the subsequent commit phase is not expanded here
    if (isCommitting) {
      // Updates that occur during commit should have synchronization priority
      expirationTime = Sync; // Expiration Time is the synchronization value
    } else {
      // Updates in the render phase should expire at the same time as updates being renderedexpirationTime = nextRenderExpirationTime; }}else {
    // No explicit expiration context is set, and React is not currently working. Calculates the new expiration time
    // Look at the ConcurrentMode concept
    if (fiber.mode & ConcurrentMode) {
      / / isBatchingInteractiveUpdates this value is usually the event interaction happens more become True so it is generally True interactive type of Expiration Time
      if (isBatchingInteractiveUpdates) {
        // Interactive Expiration Time here is the source code in the previous article
        expirationTime = computeInteractiveExpiration(currentTime);
      } else {
        // Async type Expiration Time here source code in the previous article
        expirationTime = computeAsyncExpiration(currentTime);
      }
      // If you are rendering a tree, do not update at the same time
      if(nextRoot ! = =null && expirationTime === nextRenderExpirationTime) {
        // Force changes without updating at the same time
        expirationTime -= 1; }}else {
      // Update asynchronouslyexpirationTime = Sync; }}if (isBatchingInteractiveUpdates) {
    // This is an interactive update. Track the minimum interactive expiration time to be processed. React refreshes synchronously when all interaction updates need to be updated
    if( lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime ) { lowestPriorityPendingInteractiveExpirationTime = expirationTime; }}// Return time at last
  return expirationTime;
}
Copy the code

ConcurrentMode concept

What’s the point of defining variables in binary terms? In fact, the purpose is to combine modes and determine whether there is a Mode through bit operation. In short, the purpose is to combine modes and determine whether there is a Mode. This design Mode is very useful in React

export const NoContext = 0b000;
export const ConcurrentMode = 0b001;
export const StrictMode = 0b010;
export const ProfileMode = 0b100;
Copy the code

For example,

var a = 0b000;
var b = 0b001;
var c = 0b010;
var d = 0b100;

var mode = a; // NoContext

// Check whether b exists
mode & b; / / 0
// Add the b attribute to mode
mode |= b; // set mode to 1
// Add the c attribute
mode |= c; / / 3

mode & b; // 1 already contains 1
Copy the code

summary

This section classifies the overall content. Use computeExpirationForFiber as an entry point Calculate various circumstances Expiration Time value introduced ExpirationContext context as updated by means of external Expiration Time, ConcurrentMode is a common design mode for React. Thank you for reading, we will update the various types of Expiration Time and React scheduling step by step