preface

Hello everyone! I’m front-end nameless

background

I have optimized the progress bar and improved the page performance by 70%. Many people want to know about the debugging skills of Chrome. You do it like a tiger, and you find performance problems. As a small white I, see is a face mengbi, what? Hurry up and check out the Chrome Developer Center last night, I want to be a god!

case

  1. This is a demo, comparing the three solutions to the Chrome Performance panel.

The demo code in this paper is modified based on Chrome Developers, and an optimization scheme is added for comparison.

Partial code snippet

  app.update = function (timestamp) {
      for (var i = 0; i < app.count; i++) {
        var m = movers[i];
        if (app.scheme==1) {
            / / a
            console.log("Unoptimized code");
          var pos = m.classList.contains('down')? m.offsetTop + distance : m.offsetTop - distance;if (pos < 0) pos = 0;
          if (pos > maxHeight) pos = maxHeight;
          m.style.top = pos + 'px';
          if (m.offsetTop === 0) {
            m.classList.remove('up');
            m.classList.add('down');
          }
          if (m.offsetTop === maxHeight) {
            m.classList.remove('down');
            m.classList.add('up'); }}else if(app.scheme==2) {console.log("Plan two optimized code");
           
            var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
            m.classList.contains('down')? pos += distance : pos -= distance;if (pos < 0) pos = 0;
            if (pos > maxHeight) pos = maxHeight;
             m.style.top = pos + 'px';
            if (pos === 0) {
              m.classList.remove('up');
              m.classList.add('down');
            }
            if (pos === maxHeight) {
              m.classList.remove('down');
              m.classList.add('up'); }}else if(app.scheme===3) {console.log("Plan 3 optimized code");
                var pos = parseInt(m.style.transform.slice(m.style.transform.indexOf('(') +1, m.style.transform.indexOf('px')));
                m.classList.contains('down')? pos += distance : pos -= distance;if (pos < 0) pos = 0;
                if (pos > maxHeight) pos = maxHeight;
                // m.style.top = pos + 'px';
                m.style.transform=`translateY(${pos}px)`;
                if (pos === 0) {
                m.classList.remove('up');
                m.classList.add('down');
                }
                if (pos === maxHeight) {
                m.classList.remove('down');
                m.classList.add('up');
            }
        }
      }
      frame = window.requestAnimationFrame(app.update);
    }
Copy the code

start

We use the Performance panel to look for Performance bottlenecks in the above case.

  1. To ensure that our interface performance is not affected by other Chrome plugins, we opened Google Chrome in Incognito mode.
  • Windows, Linux, or Chrome: Press Ctrl + Shift + N
  • Mac: Press ⌘ + Shift + N
  1. F12 Start DevTools and select Performance

  2. We can simulate moving the CPU, choosing X4 will be 4 times slower than usual.

Record runtime performance

For the demo, in plan 1, we can clearly see that when the blue square on the page increases to 200, the FPS has dropped from 60 to 18, showing obvious lag effect. At this time, we need to record in the performance panel to learn how to detect the performance bottleneck.

  1. In the Performance panel, click Record (the small red dot in the upper left corner) to start recording.

  1. Just wait a few seconds.

  2. Click the stop. DevTool stops recording, processes the data, and after a while automatically displays the results in the performance panel.

Arrived here to see the chart to compare meng force, so many graphs, should see that, all be what meaning!

The results of the analysis

Now that we have page performance, how do we measure the performance of the page?

FPS

An important measure of an animation’s performance is its FPS(frames per second). When the animation runs at 60FPS, it looks very coherent to the naked eye.

Bad:

good:

When we see a red bar on top of an FPS, it means our frame rate is really low and the user experience is really bad. In general, the higher the green bar, the higher the FPS. So the first thing we look at when we look at performance charts is the FPS.

CPU

The CPU chart will appear under FPS. Bad:

good:

At the bottom of the performance panel, the more color the graph shows, the CPU performance has reached its limit. When we see the CPU at maximum for a long time, we need to consider how to optimize it.

Selects a screenshot at the specified time and location

Hover over an FPS, CPU, or NET chart and DevTools displays a screenshot of the current page. Move the mouse left or right to select a range. This is useful for manually analyzing animation performance.

Frames

In the Frames section, hover the mouse over the green square, and DevTools displays the time consumed for a particular frame. It could be well below the target of 60FPS per frame.

A frame in the figure above costs 446.2ms, so it has an FPS of 2. (1000ms/446) is about 2FPS. Well below the 60FPS requirement.

More intuitive tool: the FPS meter

  1. Press Command+Shift+P (Mac) or Control+Shift+P (Windows, Linux) to open the Command menu.

  2. Enter show Rendering

3. Select FPS Meter on the Rendering TAB

  1. We can see the FPS data in real time.

Finding performance bottlenecks

We already know there is a performance problem, but what exactly is causing the problem?

  1. First we look at the Summary TAB, and we can see that the blue part takes up most of the Rendering. The blue part represents Rendering, and most of the page is devoted to Rendering. Then we need to try to reduce render time.

  2. Expand the Main section. Here is a fire chart of the main line over time. The X-axis represents time and the Y-axis represents events. Each bar represents an event, and the longer the bar, the longer the elapsed time. When you see graphs stacked, it means that events are processed at a higher rate at the same time. This can cause performance problems.

bad: good:

  1. We can see the red triangle in the upper right corner of the Animation Frame Fired. PS: The red triangle indicates that there may be a warning about problems related to this event. Note: This callback occurs whenever requestAnimationFrame() is executed.

  2. Click Animation Frame Fired, and the bottom Summary bar displays information about the event along with a link. Clicking the link takes you to the source line.

  1. You can see in the figure above that the call to app.update caused the problem.

  2. Select the app.update event and we see a bunch of purple events. Look, almost every one of them has red triangles. Pick any one and we can see more information in the Summary TAB. There is a warning about forced reflows.

If we click the link to enter the source code, we can see:

The cause was found due to: offsetTop causing backflow.

Ps: Backflow consumes more performance and costs more than drawing.

Question why

We use offsetTop to cause backflow and performance cost.

As can be seen in the figure above, backflow does not necessarily lead to redrawing, and redrawing does not necessarily lead to backflow.

What causes reflux?

  1. Change the geometry of a DOM element. Common geometry attributes include width, height, padding, margin, left, top, border, and so on.
  2. Changing the structure of the DOM tree mainly refers to adding or removing DOM nodes, moving and other operations.
  3. Gets the value of a particular attribute, such as a property: OffsetTop, offsetLeft, When offsetWidth, offsetHeight, scrollTop, scrollLeft, scrollWidth, scrollHeight, clientTop, clientLeft, clientWidth, clientHeight, Pay attention! In addition to this: a call to the getComputedStyle method also triggers backflow.

To optimize the

When I used animo.js, there was a description in the documentation:

Most CSS properties cause layouts to change or be redrawn, and animations to be unstable. Therefore, prioritize opacity and CSS transforms whenever possible.

The demo code in this paper is modified based on Chrome Developers. The second plan in the code is the official optimization plan: obtain the style.top value and modify the top value.

Scheme 2: Part of the official optimization is made by removing offsetTop to obtain the top value, but the top value is still being modified. The following is the official optimization effect:

38fps on 200 nodes

Transforms Solution 3: Transforms TOP

After optimization, we can see 200 nodes smoothly at 60fps.

The effect of post-Preformance charts was optimized

After the language

Learn now, sell now, I also want to be a god, welcome to give more advice. Give it a thumbs up! Comments are welcome.