1 the introduction

BI tools in the data center often face massive data rendering processing, in addition to component performance optimization, often check the overall page performance bottlenecks, especially when maintaining some of the old code performance is not good.

Profiling react.js Performance is a must-learn skill for Profiling react.js Performance.

2. Intensive reading

This paper introduces many performance testing tools and methods.

React Profiler

The Profiler API is a supplement to runtime Debug, and can be used as a callback to retrieve component rendering information:

const Movies = ({ movies, addToQueue }) = > (
  <React.Profiler id="Movies" onRender={callback}>
    <div />
  </React.Profiler>
);

function callback(
  id,
  phase,
  actualTime,
  baseTime,
  startTime,
  commitTime,
  interactions
) {}
Copy the code

This callback will be executed on each render, which is divided into initialization and update phases.

  • Id: indicates the id passed in.
  • Phase: “mount” or “update” : indicates the update status.
  • ActualDuration: Actual rendering time.
  • BaseDuration: Estimated rendering time without memo.
  • StartTime: start rendering time.
  • CommitTime: React Update submission time
  • Interactions: What causes the rendering, e.gsetStateOr hooks changed.

Be careful not to use profilers to detect performance because profilers themselves can be a performance drain.

If you don’t want to get such a detailed rendering time, or don’t want to bury points in the code ahead of time, you can use the DevTools Profiler to see a more intuitive and concise rendering time:

Ranked displays results sorted by rendering time. Interations need to be used with the Tracing API, which is described later.

Tracing API

Using the Trace API provided by Scheduler/Tracing, we can record the elapsed time of an action, such as how long it took to click the Add button to bookmark a movie:

import { render } from "react-dom";
import { unstable_trace as trace } from "scheduler/tracing";

class MyComponent extends Component {
  addMovieButtonClick = (event) = > {
    trace("Add To Movies Queue click", performance.now(), () => {
      this.setState({ itemAddedToQueue: true });
    });
  };
}
Copy the code

In Interations, you can see the elapsed time of action triggering:

This action can also be rendered, such as the time taken to render the ReactDOM:

import { unstable_trace as trace } from "scheduler/tracing";

trace("initial render", performance.now(), () => {
  ReactDom.render(<App />, document.getElementById("app"));
});
Copy the code

You can even track asynchrony time:

import {
  unstable_trace as trace,
  unstable_wrap as wrap,
} from "scheduler/tracing";

trace("Some event", performance.now(), () => {
  setTimeout(
    wrap((a)= > {
      // Asynchronous operation})); });Copy the code

With Profiler and Trace, we can monitor the rendering and interaction time of any element, covering almost all performance monitoring needs.

Puppeteer

Puppeteer can also be used to automate operations and print reports:

const puppeteer = require("puppeteer");

(async () = > {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const navigationPromise = page.waitForNavigation();
  await page.goto("https://react-movies-queue.glitch.me/");
  await page.setViewport({ width: 1276.height: 689 });
  await navigationPromise;

  const addMovieToQueueBtn =
    "li:nth-child(3) > .card > .card__info > div > .button";
  await page.waitForSelector(addMovieToQueueBtn);

  // Begin profiling...
  await page.tracing.start({ path: "profile.json" });
  // Click the button
  await page.click(addMovieToQueueBtn);
  // Stop profliling
  await page.tracing.stop();

  awaitbrowser.close(); }) ();Copy the code

First, create a browser using puppeteer, create a new page and open the URL https://react-movies-queue.glitch.me/. After the page is loaded, use the DOM selector to find the button. Using the Page. Click API to simulate clicking the button, tracing Performance changes before and after using page. Tracing and uploading the file to the DevTools Performance panel will give you an automatic Performance detection report:

This graph is important as it is a useful tool for analyzing the browser’s overall runtime overhead. It is divided into four sections at the top:

  • FPS: The number of frames per second. The higher the green vertical line, the higher the FPS, and the red line, the lag.
  • CPU: CPU resources. Events that consume CPU resources are displayed in an area diagram.
  • NET: network consumption, each bar represents the loading of a resource.
  • HEAP: indicates the memory water level. It is used to check whether memory consumption meets expectations because it cannot be detected in a short period of time. The detection of memory overflow needs to be reported by continuous monitoring.

A detailed diagram of a Network is shown below, such as this one:

The thin line represents the wait time, the thick line represents the actual load, and the light part represents the server wait time, which is the time from sending the download request to the first byte of the server response. This section can tell you whether there is a problem with the resource server response time or not.

Timings shows several important points in time, here are some of them:

  • FP: First Paint.
  • FCP: First Contentful Paint.
  • Largest Contentful Paint: Largest Contentful Paint
  • DCL: Document Content Loaded.

Below this is the JS calculation of consumption, using a flame chart, a commonly used visualization tool for performance analysis. Take this picture:

To look at the flame diagram, first look at the longest function, the longest line, which is the most time-consuming part. From left to right is the order in which the browser scripts are called, and from top to bottom is the order in which the functions are nested.

We can see that the function 34 at the mouse position is long, but it is not a performance bottleneck, because the following n function is as long as it is, indicating that the performance of function 34 is almost zero-loss, which is determined by the function n it calls.

In this way, we can step through the leaf nodes to find the primitive subfunctions that have the greatest impact on performance.

User Timing API

We can also use performance. Mark to customize performance detection nodes:

// Record the time before running a task
performance.mark("Movies:updateStart");
// Do some work

// Record the time after running a task
performance.mark("Movies:updateEnd");

// Measure the difference between the start and end of the task
performance.measure("moviesRender"."Movies:updateStart"."Movies:updateEnd");
Copy the code

These nodes can be displayed in the Performance panel described above for custom analysis.

3 summary

Use Performance for general Performance analysis and React Profiler for React custom Performance analysis. Together, the two can perform almost any Performance detection.

Generally speaking, the React Profiler should be used first to screen React problems, which is more intuitive and easier to locate problems. If some issues are outside the React framework or can no longer be measured at component granularity, we can go back to the Performance panel for a general Performance analysis.

React Performance Debugging · Issue #247 · 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

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