Chrome Devtools’ Performance tool is a great tool for Performance analysis and optimization because it records the time spent on each piece of code to identify Performance bottlenecks and optimize them accordingly.

Such a powerful tool must be well mastered, today we will do a Performance optimization case to quickly start Performance.

Performance analysis

First, we prepare this code:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>worker performance optimization</title>
</head>
<body>
    <script>
        function a() {
           b();
        }
        function b() {
            let total = 0;
            for(let i = 0; i< 10*10000*10000; i++) {
                total += i;
            }
            console.log('b:', total);
        }

        a();
    </script>
    <script>
        function c() {
            d();
        }
        function d() {
            let total = 0;
            for(let i = 0; i< 1*10000*10000; i++) {
                total += i;
            }
            console.log('c:', total);
        }
        c();
    </script>
</body>
</html>
Copy the code

Obviously, the two script tags are two macro tasks. The first macro task has the call stacks of A and B, and the second macro task has the call stacks of C and D.

Let’s use Performance to see if this works:

First, open Chrome in traceless mode. In traceless mode, there are no plug-ins and analysis performance will not be affected by plug-ins.

Open the Performance panel of Chrome DevTools and hit the Reload button to reload the page and start recording the elapsed time:

Click finish after a few seconds.

The interface will display the recorded information:

Main is the Main thread.

The main thread is executing the Event Loop over and over again. You can see that there are two tasks (macro tasks) with call stacks A and B and C and D, matching our analysis. (Of course, there are some internal browser functions, such as parseHtml, evaluateScript, etc., which can be ignored)

The most important function of the Performance tool is to analyze the Event Loop of the main thread and the time consuming and call stack information of each Task.

When you click on a macro task, the following panel displays the details of the call stack (bottom-up for list display, Call Tree for tree display).

The elapsed time for each function is also shown on the left, with the source address on the right, and clicking to jump to the corresponding code for Sources.

How convenient it is to directly display the time taken per line of code!

With the tools introduced, let’s analyze where the code has performance problems.

Obviously, the cycle sum of b and D is too long.

You can also see in Performance that tasks are marked red, and the summary panel below also shows warnings for Long Tasks.

Some students may ask: why optimize long Task?

Because rendering and JS execution are on the main thread, in an Event Loop, they block each other, and if JS has a long-running Task, it blocks rendering, causing the page to stall. So, the main purpose of performance analysis is to find the long Task and then eliminate it.

Perhaps many students do not know, in fact, webpage rendering is also a macro task, so it will block with JS execution. Proof of this can be found in my previous article:

Performance proves that rendering a web page is a macro task

Now that you have the code you want to optimize, and you know what you want to do (eliminate the Long Task), let’s start tuning.

Performance optimization

The goal of our optimization is to remove or split the time-consuming logic (loop accumulation) from the two long tasks into multiple tasks.

For example, see React’s optimization of the recursively rendered VDOM to the interruptible rendered VDOM of the linked list, which is the Fiber architecture, which also aims to split long tasks.

But obviously our logic here has nothing to break down, it’s just one big loop.

So can we not run on the main thread and run on another thread? Browser Web workers seem to be performance optimizations for time-consuming calculations.

Let’s try it:

Encapsulating such a function, passing in a URL and a number, the function creates a worker thread that passes num through postMessage and listens for message events to receive the returned data.

function runWorker(url, num) {
    return new Promise((resolve, reject) = > {
        const worker = new Worker(url);
        worker.postMessage(num);
        worker.addEventListener('message'.function (evt) {
            resolve(evt.data);
        });
        worker.onerror = reject;
    });
};
Copy the code

Then the b and C functions can be changed like this:

function b() {
    runWorker('./worker.js'.10*10000*10000).then(res= > {
        console.log('b:', res);
    });
}
Copy the code

Time logic moved to worker thread:

addEventListener('message'.function(evt) {
    let total = 0;
    let num = evt.data;
    for(let i = 0; i< num; i++) {
        total += i;
    }
    postMessage(total);
});
Copy the code

Perfect. Let’s try it again:

Wow, there are no long tasks!

You’ll also notice that there are two more Worker threads below the Main thread:

The Worker still has long tasks, but it doesn’t matter because the computation is there, as long as the main thread doesn’t have long tasks.

In this way, by splitting the computation into worker threads, we make full use of the ability of multi-core CPU to solve the long task problem of the main thread, and the interface interaction will be smooth.

Let’s take a look at the Sources panel:

Compare the previous ones:

This optimization strength is visible to the naked eye!

In this way, we completed a webpage performance optimization together, analyzed long tasks through Peformance, located time-consuming codes, and optimized them through worker splitting computation, successfully eliminating long tasks in the main thread.

If you are interested, you can use the Performance tool to analyze the code:

Github.com/QuarkGluonP…

conclusion

The Performance tool of Chrome Devtools is a powerful tool for analyzing web page Performance. It can record the code execution in a period of time, such as the Event Loop of the Main thread, the Task of each Event Loop, and the call stack of each Task. The time taken for each function, etc., can also be located to the source location in Sources.

The goal of performance optimization is to find the long Task in the Task and eliminate it. Because webpage rendering is a macro task, and JS macro task in the same Event Loop, are blocking each other.

We made a real optimization case, and analyzed the time-consuming part of the code through Performance, which was found to be caused by the large amount of calculation. Therefore, we split the calculation logic into worker threads to make full use of the parallel processing ability of multi-core CPU and eliminate the long task of the main thread.

After this performance optimization example, did you find the Peformance tool easy to use?

In fact, it can analyze the Event Loop of the main thread, analyze the Task and the call stack of the Task, find out the long Task, and locate the time-consuming code. The Performance tool has mastered most of the functions, and these are the commonly used functions.