React source code-knowledge points

调合 reconciliation

React is used to diff one tree with another to determine which parts need to be changed.

  • Assume that different component types generate different trees. React does not try to change them, but the new tree completely replaces the old tree
  • The diff of the list is implemented with the key. The key should be unique, predictable, and safe
    . The reconciler is just the calculation of which part of the tree has changed and the renderer (web, ios, android), and the Fiber re-implements the reconciler.
Schedule
  • It is the process of deciding when to perform work.
  • If some work does not need to be displayed on the UI interface immediately, we can delay any logic related to it.
  • If the data arrives faster than the frame rate, we can merge and batch update
  • We should prioritize user interaction functions and delay data loading to prevent frame loss.

key point

  • In the UI interface, not every update needs to be executed immediately, which will drop frames and reduce user experience
  • Different updates have different priorities, such as animation updates need to be completed faster than loading data
  • In fiber, the core algorithm of React is reformed using scheduling
Interruptible rendering

eg A filterable list. If the input is updated every time, performance problems will occur. If anti-shake and throttling are used, it will also affect the user experience.
The main reason is that rendering cannot be interrupted, blocking rendering

Concurrent Mode
  • React can handle multiple status updates at the same time
  • blocking rendering blocking rendering, such as when creating a new DOM and executing component code, cannot be suspended
  • In parallel mode, rendering is not blocking and can be interrupted
  • Concurrency mode is similar to React "working on a branch"
  • In Concurrent Mode, before entering the next state UI, react will now be calculated in memory, and will stay in the old state UI for a while, so that there is a better user experience
  • 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.
  • 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.
Work

Is the result of calling update (setState)

In order to take full advantage of scheduling, we need to implement

  • Pause and resume of tasks
  • Assign priority to different tasks
  • Reuse completed work
  • Give up unwanted work
Fiber (A fiber represents a unit of work)

Progressive rendering, split a rendering into multiple chunks, and distribute them in multiple frames. Other key features include the ability to pause, abort or reuse work when new updates arrive;
the ability to assign priorities to different types of updates, and original New concurrency features.

  • Fiber is a re-implementation of call stack, a customized call stack
  • Each fiber is a frame of a virtual call stack

requestIdleCallback assigns a low-priority job
requestAnimationFrame assigns a high-priority job
We need to manually manipulate stack frames

Fiber detail
  • Fiber is an object that contains components, component input and output
  • Fiber corresponds to a stack frame and also corresponds to a component instance
  • The two fields of type and key are the same as the performance of normal components. Type describes the type of the component. The type that matches the component is itself, and the host component is the string "div".
  • With the type field, the key is used in the blending phase, which fibers can be reused
  • child is the component returned by the parent component's render method
  • siblings are adjacent components
  • return is the fiber returned after processing the fiber, if there are multiple child fibers, the parent fiber is returned
  • When the pendingProps starts, the parameter memoizedProps is set after the end, if the two are the same, it means that the last result can be reused
  • Flush a fiber is to input the result into the UI
  • work-in-progress An unfinished fiber is a stack frame without return
  • A component has two fibers, a completed flushed fiber and a work-in-progress fiber alternate is the mutual value of the two fibers
  • The alternate of a fiber is created lazily. The cloneFiber created using cloneFiber will reuse the existing alternate, if any
  • The final return of each fiber is HostComponent (div)
Number of frames

When the number of frames drawn per second (FPS) reaches 60, the page is smooth. When it is less than this value, the user will feel stuck. 1s 60 frames, so the time of each frame is 1000/60 ≈ 16 ms. The
following six steps need to be completed within one frame to process user interaction, JS analysis execution, and frame start. Window size change, page scrolling, etc. processing, requestAnimationFrame (rAF), layout, and drawing. After the
above six steps are completed, it does not exceed 16 ms, indicating that there is enough time. At this time, the tasks registered in requestIdleCallback will be executed. But requestAnimationFrame must be executed every frame.

performance

The Performance interface provides access to the performance-related information of the current page, which mainly contains 4 attribute parts,

  • timing Legacy PerformanceTiming object containing performance information related to delay
  • navigation is a legacy PerformanceNavigation object that provides useful context about the operations contained in the time listed, including whether the page is loaded or refreshed, how many redirects have occurred, and so on.
  • memory A non-standard extension is added to Chrome. This attribute provides basic memory usage information for an object. You should not use this non-standard API
  • timeOrigin returns the high-precision time stamp of the start time of the performance measurement (3 precision time stamps)

performance methods

  • performance.now() returns a timestamp with milliseconds (milliseconds) accuracy. The returned value represents the elapsed time from the time source.
const t0 = performance.now();
doSomething();
const t1 = performance.now();
console.log(`Call to doSomething took ${
    
    t1 - t0} milliseconds.`);
  • mark creates a timestamp in the browser's performance input buffer with the given name
  • start to measure
const markerNameA = "example-marker-a"
const markerNameB = "example-marker-b"

// Run some nested timeouts, and create a PerformanceMark for each.
performance.mark(markerNameA);
setTimeout(function() {
    
    
  performance.mark(markerNameB);
  setTimeout(function() {
    
    

    // Create a variety of measurements.
    performance.measure("measure a to b", markerNameA, markerNameB);
    performance.measure("measure a to now", markerNameA);
    performance.measure("measure from navigation start to b", undefined, markerNameB);
    performance.measure("measure from the start of navigation to now");

    // Pull out all of the measurements.
    console.log(performance.getEntriesByType("measure"));

    // Finally, clean up the entries.
    performance.clearMarks();
    performance.clearMeasures();
  }, 1000);
}, 1000);

Guess you like

Origin blog.csdn.net/qq_29334605/article/details/106136826