Front-end high performance scrolling scroll and page rendering optimization

Source: Internet
Author: User
Tags parallax website


Objective

Recently in the study of page rendering and web animation performance issues, as well as the reading of the CSS SECRET (CSS) this masterpiece. This article mainly wants to talk about the optimization of the page scrolling optimization.

The main content includes why you need to optimize scrolling events, scrolling and page rendering relationships, throttling and anti-shake, pointer-events:none optimized scrolling. Because this article involves a lot of foundation, is my own study record of a process, if the above listed knowledge points are clear in the chest, you can not have to look down.

The origin of rolling optimization

Scrolling optimization is not just about scrolling (scroll events), it also includes events such as resize, which are frequently triggered. A simple look:

var i = 0;window.addeventlistener (' scroll ', function () {console.log (i++);},false);

The output is as follows:

When you bind an event such as scroll, resize, when it occurs, it is triggered very frequently and at close intervals. If the event involves a large number of positional computations, DOM operations, element repainting, and so on, which cannot be completed before the next scroll event is triggered, the browser will drop the frame. In addition to the user's mouse scrolling is often continuous, will continue to trigger the scroll event resulting in dropped frames, increased browser CPU usage, the user experience is affected.

There are also many application scenarios for binding callbacks in scrolling events, such as lazy loading of images, sliding auto-loading data, and side floating navigation bar.

When a user browses a Web page, having smooth scrolling is often overlooked but is a vital part of the user experience. When the scrolling performance is normal, the user will feel the application is very smooth, pleasing, on the contrary, cumbersome and natural rolling, it will give users a great feeling of uncomfortable.

The relationship between scrolling and page rendering

Why do scrolling events need to be optimized? Because it affects performance. So what does it do to affect performance? The amount of ... This is going to start with the question of what the page performance is about.

I think the technology must be traced back, do not see someone else an article said that the rolling events will lead to stalling and said a bunch of solution optimization techniques unsanitary environment mantras, we need is not take doctrine but criticism, more to the source to see.

From the point of view, step by step to find the last, it is easy to find the crux of the problem, only so that the solution is easy to remember.

Preach a bunch of crap, don't like directly ignore Ha, back to the point, to find the optimization of the entrance to know where the problem is, for page optimization, then we need to know the page rendering principle:

Browser rendering principle I'll go into the details in my last article, but more of it is from the perspective of animation rendering: "Web Animation" CSS3 3D planetary Operation && Browser rendering principle.

Think, or simply describe, I found every time review these knowledge points have a new harvest, this time for a picture, to Chrome as an example, a Web page display, simply can be considered to experience the following next few steps:

    • JavaScript : In general, we use  JavaScript  to achieve some of the effects of visual change. For example, make an animation or add some  DOM  elements to the page.

    • style: calculation style, this process is based on the  CSS  selector, each  DOM  element matches the corresponding  CSS  Style. By the end of this step, you determine what  CSS  style rules apply to each  DOM  element.

    • layout: layouts, the previous step determines the style rules for each  DOM  element, and this step is to calculate each  DOM  The size and position that the element will eventually appear on the screen. The layout of the elements in the web  page is relative, so that the layout of one element changes, and the layout of other elements is changed by linkage. For example, the change in the width of the,<body>  element affects the width of its child elements, and the change in its child width will continue to affect its grandson elements. As a result, the layout process often occurs for browsers.

    • Paint: Drawing is essentially the process of populating pixels. This includes drawing text, colors, images, borders, and shadows, all of which are visual effects of a  DOM  element. In general, this drawing process is done on multiple layers.

    • Composite: render layer Merge, from the previous step, the drawing of  DOM  elements in the page is done on multiple layers. After the drawing process is completed on each layer, the browser merges all layers into one layer in a reasonable order and then displays them on the screen. This process is especially important for pages that have overlapping elements, because when the merge order of the layers goes wrong, it causes the element to show an exception.

Here again the concept of layer (Graphicslayer) is involved, the Graphicslayer layer is passed on to the GPU as a texture (texture), and now it is often seen that GPU hardware acceleration is closely related to the concept of the so-called layer. But with the rolling optimization of this article is not very relevant, interested in-depth understanding of Google more can be self.

Simply put, when a page is generated, it will render at least once (layout+paint). During user access, the Reflow and redraw (repaint) are continually re-queued.

Among them, user scroll and resize behavior (that is, sliding the page and changing the window size) will cause the page to constantly re-render.

When you scroll the page, the browser may need to draw some pixels in these layers (sometimes referred to as the composition layer). By grouping elements, when the content of a layer changes, we only need to update the structure of that layer, and simply redraw the part that changes in the render layer structure without having to redraw it completely. Obviously, if when you roll, like a parallax website (poke me look) so something moves, it's possible that multiple layers lead to large areas of content adjustment, which leads to a lot of drawing work.

Anti-Shake (debouncing) and throttle (throttling)

The scroll event itself triggers a re-rendering of the page, while the handler of the scroll event is triggered by the high frequency, so there should be no complex operations inside the handler of the event, such as DOM operations should not be placed in event handling.

For this kind of high-frequency triggering event problems (such as page scroll, screen resize, monitoring user input, etc.), the following describes two common solutions, anti-shake and throttling.

Anti-shake (debouncing)

The anti-shake technique is the ability to combine multiple sequential calls into one, that is, the number of times the event is triggered within a certain amount of time.

In layman's terms, take a look at the following simplified example:

Simple anti-jitter functions function Debounce (func, wait, immediate) {//timer variable var timeout;        return function () {//each time the scroll handler is triggered, the timer cleartimeout (timeout) is cleared;    Specify XX MS to trigger the action you really want to take handler timeout = SetTimeout (func, wait); };};/ /actually want to bind the Handlerfunction Realfunc () {Console.log ("Success") on the scroll event;} The use of anti-jitter window.addeventlistener (' scroll ', debounce (realfunc,500)),//Not using anti-jitter window.addeventlistener (' scroll ', REALFUNC);

The above simple anti-shake example can get the browser to try, the approximate function is if the 500ms does not trigger two consecutive scroll events, then will trigger we really want to trigger in the Scroll event function.

The example above can be better encapsulated:

Anti-jitter functions function Debounce (func, wait, immediate) {var timeout;        return function () {var context = this, args = arguments;            var later = function () {timeout = null;        if (!immediate) func.apply (context, args);        };        var callnow = immediate &&!timeout;        Cleartimeout (timeout);        Timeout = SetTimeout (later, wait);    if (Callnow) func.apply (context, args); };}; var myefficientfn = debounce (function () {//Real action in scrolling}, 250);//Binding monitoring Window.addeventlistener (' resize ', MYEFFICIENTFN);
Throttle (throttling)

The anti-shake function is really good, but there are problems, pedagogical gardening piece of lazy loading, I hope in the process of falling pictures are constantly loaded out, and not only when I stop the slide, the picture is loaded out. or the AJAX request loading of the data at the time of the dip is also the same.

At this time, we hope that even if the page is constantly scrolling, but the scrolling handler can also be triggered at a certain frequency (such as 250ms triggered once), such a scenario, it is necessary to use another technique, called the throttle Function (throttling).

The throttle function, which allows only one function to execute within an X-millisecond, is only allowed to make the next call to the function after the last function has elapsed the time interval you have specified.

The main difference between the throttle function and the shake-out is that it guarantees that at least one event handler that we wish to trigger is executed within X milliseconds.

Compared with the anti-shake, throttling function more than a Mustrun attribute, representing Mustrun milliseconds, will inevitably trigger a handler, the same is the use of timers, see a simple example:

Simple throttling functions function throttle (func, wait, Mustrun) {   var timeout,        starttime = new Da Te ();    return function () {       var context = This,            a RGS = arguments,            curtime = new Date ();        cleartimeout (timeout);        //If the specified trigger interval is reached, trigger handler        if (curtime-starttime >= mustrun) {            func.apply (Context,args);            starttime = Curtime;        //does not reach the trigger interval, reset timer        }else{          &NBSP;T Imeout = SetTimeout (func, wait);        }    };};/ /actually want to bind handlerfunction Realfunc () {   console.log ("Success") on the scroll event;} The throttle function window.addeventlistener (' scroll ', throttle (realfunc,500,1000)) was adopted.

The above simple throttle function example can get the browser to try, presumably the function is if in a period of time scroll trigger interval has been shorter than 500ms, then can guarantee the event we want to call the handler at least within 1000ms will be triggered once.

Use RAF (requestanimationframe) to trigger scrolling events

The jitter and throttling implementations described above are based on the timer setTimeout, but if the page only needs to be compatible with a high-version browser or application on the mobile side, or if the page requires a high-precision effect, then the native method of the browser can be used RAF (Requestanimationframe).

Requestanimationframe

Window.requestanimationframe () This method is used to notify the browser to invoke a specified function before the page is redrawn. This method takes a function as a parameter, which is called before redrawing.

RAF is often used in the production of web animation, to accurately control the page frame refresh rendering, so that the animation more smooth, of course, its role is not limited to animation production, because it is also a timer.

Normally, the RAF is called 60 times per second, or 1000/60, and the trigger frequency is about 16.7ms.

In simple terms, using requestanimationframe to trigger a scrolling event is equivalent to the above:

Throttle (func, XX, 16.7)//xx does not repeat triggering events in XX MS Handler

A simple example is as follows:

var ticking = false;    RAF Trigger Lock function onscroll () {if (!ticking) {requestanimationframe (realfunc);  ticking = true;    }}function Realfunc () {//do something ... console.log ("Success"); ticking = false;} Scrolling Event Listener window.addeventlistener (' scroll ', onscroll, false);

The above simple use of the RAF example can get the browser to try, presumably the function is in the process of scrolling, to maintain the frequency of 16.7ms to trigger the event handler.

The advantages and disadvantages of using requestanimationframe coexist, first we have to consider its compatibility problem, and secondly because it can only be implemented at 16.7MS frequency to trigger, on behalf of its very poor adjustability. But when it comes to more complex scenes than throttle (func, XX, 16.7), the RAF may be better and more performance-effective.

Summarize

Anti-Shake: the Technology of image stabilization is that multiple sequential calls can be combined into one, that is, the number of times the event is triggered within a certain amount of time.

Throttle function: Only one function is allowed to execute within X milliseconds, and the next call to the function is made only after the last function has elapsed the time interval you have specified.

The RAF:16.7MS triggers a single handler, reducing controllability but improving performance and accuracy.

Simplifies operation within the scroll

The methods described above are how to optimize the triggering of scroll events to avoid scroll events consuming resources excessively.

But in essence, we should try to streamline the handler of the scroll event, and the initialization of some variables, the calculation that does not depend on the change of the scrolling position, should be ready in advance outside of the scroll event.

The recommendations are as follows:

Avoid modifying style properties in the scroll event / stripping style operations from the scroll event

Input event handlers, such as the handling of Scroll/touch events, are invoked before requestanimationframe.

Therefore, if you do the action of modifying the style properties in the handler function of the scroll event, then these actions will be staged by the browser. Then, when calling Requestanimationframe, if you do the reading of the style property at the beginning, this will cause the browser's forced synchronization layout to be triggered.

Attempt to use Pointer-events:none to suppress mouse events during sliding

Most people may not know this attribute, well, then what is it for?

Pointer-events is a CSS property, can have a number of different values, a part of the value of the property is only associated with SVG, here we only focus on the situation of Pointer-events:none, is probably meant to prohibit mouse behavior, after applying the attribute, such as mouse click, Functions such as hover will fail, that is, the element will not become the target of the mouse event.

You can open the Developer Tools panel near F12, add a pointer-events:none style to the <body> tab, and then feel the effect on the page, and find all mouse events are banned.

So what's the use of it?

Pointer-events:none can be used to increase the frame rate when scrolling. Indeed, when scrolling, the mouse hovers over certain elements, triggering the hover effect on it, but these effects are usually not noticed by the user and tend to cause problems with scrolling. Applying pointer-events:none to the BODY element disables mouse events, including hover, to improve scrolling performance.

. disable-hover {    pointer-events:none;}

The general idea is to add the. Disable-hover style to <body> when the page scrolls, and all mouse events will be banned until the scrolling stops. When the scroll is finished, remove the property.

You can view this demo page.

It says that Pointer-events:none can be used to increase the frame rate when scrolling from POINTER-EVENTS-MDN, but also specifically an article to explain the technology:

Use Pointer-events:none to implement 60fps scrolling.

Is that it? No, Zhang Xin Xu has a special article to explore whether Pointer-events:none can really speed up the rolling performance, and put forward their own doubts:

Pointer-events:none improve the drawing performance when scrolling the page?

Conclusion a matter of opinion, the use of Pointer-events:none on the occasion of the business itself to decide, refused to take doctrine, more to the source to see, hands-on practice to make a decision.

Other references (all good articles, worth reading):

    • Instance resolution stabilization (debouncing) and throttle valve (throttling)

    • Wireless performance Optimization: Composite

    • JavaScript high performance animations and page rendering

    • Google developers– Rendering Performance

    • Web High Performance animations

To this end of this article, if there are any questions or suggestions, you can communicate a lot, original articles, writing limited, Caishuxueqian, if there is not in the text, million hope to inform.

Front-end high performance scrolling scroll and page rendering optimization

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.