Use Chrome Timeline to optimize page performance

Source: Internet
Author: User
Tags acos cos

Use Chrome Timeline to optimize page performance

Sometimes, we will automatically write some inefficient code, seriously affect the efficiency of the page run. Or we take over the project, the previous code written by many strange, such as for a Canvas special effects need to draw 600 triangles simultaneously, such as Coding.net's task center needs to watch tens of thousands of variable changes and so on. So, if we come across a more inefficient page, how do we optimize it?

Preparation before optimization: knowing the enemy

Before we begin, let's start by opening the F12 panel and familiarize yourself with the tools we'll use Next: Timeline:

Yes, that's it. Let me introduce you here. Area 1 is a thumbnail, you can see in addition to the time axis is divided into four blocks, respectively, representing FPS, CPU time, network communication time, stack occupancy; this thumbnail can be scaled horizontally, and the white area is the time period (gray of course not visible) that can be seen below. Area 2 You can see some interactive events, such as you scroll the page, then there will be a scroll line segment, the range of coverage is the time to scroll through. Zone 3 is a specific list of events.

When there is no record at first, all the areas are empty. Start statistics and end statistics are very simple, the upper left corner of the black Circle is. The button on the right that looks like a "no pass" is used to clear existing records. When there is data, we roll up the mouse wheel and we can see that the area is enlarged:

In a short time, the browser has done so many things. For the general screen, in principle, a second to draw 60 frames to the screen, so in theory we can not calculate the time in a frame more than 16 milliseconds, but the browser in addition to execute our code, but also to do something else (such as the calculation of CSS, playing audio ...) ), so in fact we can only use about 10~12 milliseconds.

Almost familiar with the operation, then come to the actual combat it! If one day, you took over a piece of code like this:

<!--a little animation: after clicking the button there will be an exploded particle effect--<! DOCTYPE html><Html><Head><meta charset= "Utf-8" ><title>Test</title><style>. Main {position:relative;width:500px;height:500px;Background: #000;Overflow:hidden;}. Circle {Position:absolute;border-radius:50%; border:1px solid #FFF;  width:8px;  height:8px; } </style></< Span class= "Hljs-title" >head><body>< Span class= "Hljs-code" > <div class= "main" ></div>  <button onclick= "showanimation ()" > Point I </button> < Script src= "jquery.min.js" ></script> <script src= "Animation.js" ></ Script></body>< Span class= "Hljs-tag" ></HTML>        
animation.js//total number of particles var COUNT = 500;//gravity var G = -0.1;//friction var F = -0.04;function init () {for (var i = 0; i < COUNT; i++) {var d = math.random () * 2 * MATH.PI;var v = math.random () * 5;var circle = $ (' <div id= "circle-' + i + '" class= "Circle" data-x= "+" data-y= "+" data-d= "' + D + '" data-v= "' + V + ' ></div> ');Circle.appendto ($ ('. Main '));}}function updatecircle () {for (var i = 0; i < COUNT; i++) {var x = parsefloat ($ (' #circle-' + i). attr (' data-x '));var y = parsefloat ($ (' #circle-' + i). attr (' data-y '));var d = parsefloat ($ (' #circle-' + i). attr (' data-d '));var v = parsefloat ($ (' #circle-' + i). attr (' data-v '));var vx = v * Math.Cos (d);var vy = v * Math.sin (d);if (Math.Abs (VX) < 1E-9) VX = 0;Change in speed componentVX + = F * Math.Cos (d);VY + = F * Math.sin (d) + G;Calculate New speed V = MATH.SQRT (VX * vx + VY * vy);  if (Vy > 0) d = math.acos (vx/v);  else D =-math.acos (vx/v); //Shift component Change  x + = Vx; Y + = Vy; $ (' #circle-' + i). attr (' Data-x ', x);  $ (' #circle-' + i). attr (' data-y ', y);  $ (' #circle-' + i). attr (' data-d ', d);  $ (' #circle-' + i). attr (' data-v ', V);  $ (' #circle-' + i). css ({' Top ': 400-y, ' Left ': x}); }}var interval = null;function showanimation () { if (interval) Clearinterval (interval);  $ ('. Main '). html (');  init ();  interval = SetInterval (updatecircle, 1000/60);}       

The effect is as follows (the FPS counter in the upper-right corner comes with the Chrome debugging tool):

Only ten FPS ... Ten FPS ... Where's The pit daddy?

OK, open the Timeline, press the Record button, click on the page "point Me", a little later stop recording, you will get some data. Zoom in a bit, as you can see from the more familiar of jquery, these are mostly jquery functions. Let updateCircle 's click on that block and look at the following:

This tells us how long this function has been running and where the function code is. We click on the link and jump to the Source page:

is not very shocking, this page was just used for debugging, did not expect to now actually brought accurate to the line of running time statistics. This time, of course, is the time that this line is running in the "Execution time period for the chunks we clicked on just now". So let's take the slowest few words to do it!

Optimize one: Reduce DOM operations

Seeing these lines of code, the first reaction is: Mdzz. The DOM is slow to operate, and it's going to be between the string and float. Be decisive! Then a separate array is used to store,,, and x y d v these properties.

var objects = [];// 在 init 函数中objects.push({    x: 250,    y: 250,    d: d,    v: v});// 在 updateCircle 函数中var x = objects[i].x;var y = objects[i].y;var d = objects[i].d;var v = objects[i].v;// ….objects[i].x = x;objects[i].y = y;objects[i].d = d;objects[i].v = v;

The effect is remarkable! Let's look at the exact data for the row:

Optimization Two: Reduce unnecessary operations

So the most time-consuming sentence has become a computational vx and vy , after all, the trigonometric algorithm is more complex, it can be understood. As for why the trigonometric function behind is so fast, I guess the Chrome V8 engine will cache it (this is not guaranteed to be correct). However, I do not know if we have found that the calculation is d completely unnecessary! We only need to save vx and vy can, do not need to save v and d !

Initvar VX = v * Math.Cos (d); var vy = v * Math.sin (d); Objects.push ({X:250,Y:250,VX:VX,Vy:vy});//Updatecirclevar VX = Objects[i].vx;var VY = objects[i].vy;//Compute new speed var v = math.sqrt (VX* VX + vy * vy); if (Math.Abs (VX) < 1e-9) VX = 0;//speed component change VX + = f * VX/ V; vy + = f * vy/v + g;//... objects[i].VX = VX; objects[i].vy = vy;              

Only subtraction and open-squared operations, each time less than the original two milliseconds. From a fluent point of view, you can actually run a full frame, but why do I still feel a little bit of a card occasionally?

Optimization Three: Replace SetInterval

Since the occasional drop frame, then see how it was dropped. In principle, before each browser is drawn, there should be an event called paint in Timeline, like this:

Did you see these green things? That's them! Look at the timeline above, although the length of the setinterval in the code is 1000/16 milliseconds, but in fact there is no guarantee! So we need requestAnimationFrame to use it instead. This is the browser's own function specifically for animation services, the browser will automatically optimize the function of the call time. And if the page is hidden, the browser will also automatically pause the call, effectively reducing the CPU overhead.

// 在 updateCircle 最后加一句requestAnimationFrame(updateCircle);// 去掉全部跟 setInterval 有关的句子,把 showAnimation 最后一句直接改成这个updateCircle();

We can at least guarantee that every time we count it, it will be displayed on the screen once, so we will not drop frames (provided that each calculation is less than 12ms). But although the calculation time is low, the browser recalculates the style, the time to draw the image has not changed a bit. Can we do the optimization again?

Optimization Four: Use hardware acceleration, avoid repeatedly finding elements

If we use  transform   to replace  left   and  top   to locate the element, then the browser will create a separate composite layer for this element, dedicated to rendering using the GPU, so that the cost of recalculation can be minimized. Interested students can look at the "CSS hardware acceleration" mechanism. At the same time, we can cache the elements of jQuery (or DOM elements) so that we do not have to re-search each time, but also a little bit more efficient. If the element is cached in the  objects   Array, then even the ID is not written!

// initvar circle = $(‘<div class="circle"></div>‘);objects.push({ x: 250, y: 250, vx: vx, vy: vy, // 其实可以只存 DOM,不存 jQuery 对象 circle: circle[0]});// updateCircle 里面 for 循环的最后一句话替换掉objects[i].circle.style.transform = ‘translate(‘ + x + ‘px, ‘ + (400 - y) + ‘px)‘;

Does it look like it's cool?

In fact, the optimization is endless, for example, I init can not use jQuery in the function, instead of createDocumentFragment splicing elements, so that the initialization time can be sharply shortened, the order of several statements in the exchange, the efficiency of the updateCircle V8 engine may be a certain increase, or even can be combined Profile panel to analyze memory footprint, view browser drawing details ... However, personal feelings are not optimized to such a limit. For a project, it is very uneconomical to write some strange code simply for optimization.

P.S. All the code here, welcome to The Spit Groove:

Not optimized version | Optimized version

Use Chrome Timeline to optimize page performance

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.