Small programs are being developed recently. Similar to VUE, they all have a life cycle.

OnLoad listens for page loading

OnReady the first rendering of the onShow listening page is complete

What the hell does that mean?

So this touched my knowledge blind area again, but the project was almost completed in the stumbling, but encountered performance problems of CSS3 animation rendering, so I was also forced, and then back to the process of rendering web pages from the browser, to find the crux of animation stuck.

The web page rendering process is as follows:

Creating a Document Object Model (DOM) using HTML

Create CSS object model with CSS (CSSOM) Execute Scripts based on DOM and CSSOM (Scripts) merge DOM and CSSOM to form a Render Tree (Render Tree) Use the Layout of all elements in the Render Tree Paint all elements

You can combine this front-end performance optimization from Alon with the display page layout of android developer options.

Android developer options display page layout

How to determine whether mobile app is native, WebView or Hybird?

To make it simple, a big chunk of the app is white without red lines, but it has buttons, images, etc., so it’s a WebView, which is data requested through a fake browser, and when you open the app when you’re off the Internet nothing is displayed on it

OnLoad listens for page loading. After rendering the interface, that is, after generating the native interface through the configuration items in. Json, it starts rendering the part of the WebView, and a page will be called only once. The onReady listening page is called only once after the first rendering of a page, indicating that the page is ready to interact with the view layer. OnShow listens to the page display and calls its functions every time the page is opened.

Where should we put our animation?

I should put it in onShow, because then I can see the animation every time I open it.

Why is it stuck?

It’s important to note that front-end developers know that browsers run single-threaded. But let’s be clear about the following concepts: single thread, main thread, and composite thread.

Although it is said that browsers execute JS in a single thread (note that execution is not meant to say that browsers only have one thread, but rather runing), the browser actually has two important threads of execution, and these two threads work together to render a web page: the main thread and the composite thread.

In general, the main thread is responsible for: running JavaScript; Calculates CSS styles for HTML elements; Page layout; Drawing elements to one or more bitmaps; Pass these bitmaps to the composition thread.

Accordingly, the composition thread is responsible for: drawing bitmaps to the screen via the GPU; Notifies the main thread to update bitmaps of visible or soon-to-be-visible portions of the page; Figure out which parts of the page are visible; Figure out which parts of the page are about to become visible as you scroll; As you scroll the page, move the elements into the viewable area.

So why does it cause animation lag?

The reason is that the main thread and composite thread are not scheduled properly.

The following details the reasons for unreasonable scheduling.

If you use height, width, margin, and padding as transition values, the browser’s main thread is overloaded, for example, from margin-left: Margin-left :-19px,margin-left:-18px, all the way to margin-left:0. The compositing process needs to draw to GPU and then render to screen, and a total of 20 main-thread renderings, 20 compositing thread renderings, 20+20 times, a total of 40 calculations.

For the rendering process of the main thread, please refer to the web page rendering process of the browser:

Creating a Document Object Model (DOM) using HTML

Create CSS object model with CSS (CSSOM) Execute Scripts based on DOM and CSSOM (Scripts) merge DOM and CSSOM to form a Render Tree (Render Tree) Use the Layout of all elements in the Render Tree Paint all elements

That is, the main thread needs to perform the Scripts, Render Tree,Layout, and Paint phases each time.

For example, tranform:translate(-20px,0) to transform: Translate (0,0), The main thread only needs to tranform:translate(-20px,0) to transform:translate(0,0) once, and then the composite thread needs to convert -20px to 0px once, for a total of 1+20 calculations.

Some people may say, this is only 19 times, what good performance improvement?

Let’s say 10ms at a time.

This reduces the elapsed time by about 190ms.

Some people will say, spicy chicken, only 190ms, it doesn’t matter.

So if the margin-left is -200px to 0, 10ms at a time, 10ms*199≈2s.

Some people say, spicy chicken, just 2s, it doesn’t matter.

Did you forget the single thread thing?

If the page has 3 animations, 3*2s=6s, which is the performance improvement of 6s. Since the data is guesswork, I will not consider its authenticity for the time being. Later in this article, I did an experiment using Chrome DevTools performance.

We should know that in today’s “customer first” era, good user experience is a rule that all products must abide by. Whether for developers or product managers, the pursuit of extreme performance is a necessary quality for us to create a good product.

If you are not familiar with the main thread, composite thread and how they work on two different animation schemes after reading my unprofessional analysis, you can check out a translated blog post (the original English link is no longer available) : Dive deep into the browser to understand the performance issues of CSS Animations and Transitions

This article perfectly explains the difference between the main thread and the composite thread in the browser, and gives a comparison of two animation schemes that vary in height from 100px to 200px. It also gives a detailed description of how the main thread and the composite thread work.

To recap, cSS3 animation caton’s solution: When using CSS3 transtion to animate effects, choose transform over height, width, margin and padding.

Transform provides rich apis such as Scale, Translate, rotate, and so on, but compatibility needs to be considered when using transform. But in fact, for most CSS3, mobile support is good, desktop support needs special attention.


Supplement: In order to enhance the persuasive power of this article, I specially did an experiment at home, the code is as follows.

<! DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .margin-transition{ /* margin-left: 0; * / background: rgba (0,0,255,0.3); transition: margin-left 1s; }. Transform-transition {/* transform: translate(0,0); * / background: rgba (0255,0,0.3); transition: transform 1s; } .common{ height: 300px; width: 300px; } </style> </head> <body> <div class="margin-transition common" id="marginTransition"> <p>transition:margin-left 1s</p> </div> <div class="transform-transition common" id="transformTransition"> <p>transition:tranform 1s</p> </div> <button Id ="control"> </button> <script> var BTN = document.getelementbyid ('control'); var marginTransition = document.getElementById('marginTransition'); var transformTransition = document.getElementById('transformTransition'); btn.addEventListener("click",function(){ console.log(marginTransition.style,transformTransition.style) marginTransition.style.marginLeft = "500px"; transformTransition.style.transform = "translate(500px,0)" }) </script> </body> </html>Copy the code

I’ll use chrome DevTools’ Performance tool to compare the performance differences. First look at the margin animation, dynamically modify the MARGin-left value of DOM node from 0 to 500px; .

transition: margin-left 1s;
Copy the code

Take a look at the transform animation, which dynamically modifies the DOM node’s transform value from Translate (0,0) to translate(500px,0).

transition: transform 1s;
Copy the code

Maybe the picture is not a good illustration of the performance difference, so let’s draw a time comparison table to facilitate our calculation.

Time consuming margin transform
Summery 3518ms 2286ms
Scripting 1.8 ms 2.9 ms
Rendering 22.5 ms 6.9 ms
Painting 9.7 ms 1.6 ms
Other 39.3 ms 25.2 ms
Idle( browser is waiting on the CPU or GPU to do some processing) 3444.4 ms 2249.8 ms
GPU usage 4.1 MB 1.7 MB
According to the above table, we can calculate the performance difference parameters when CSS3 animation effect is realized by the combination of open margin, Transform and transition.
Key performance parameters margin transform
Actual animation time (total time minus idle time) 73.6 ms 36.2 ms

It is calculated that the time of Transform animation is about 0.49 times that of Margin animation, and the performance optimization is 50%.

Since I am not very clear about the specific things done by Other, the actual animation time here may also be subtracted from the time in Other. The following table is the data after subtraction.

Key performance parameters margin transform
Actual animation time (total time minus other time and idle time) 34.3 ms 11ms

It is calculated that the time of Transform animation is about 0.32 times that of Margin animation, and the performance optimization is close to 70%.

That is, whether or not we subtract Other’s time, our transform animation is faster than margin animation.

Inaccurately, a small conclusion is drawn: Transform performance is 50%~70% better than margin.

Although there will be a 50% to 70% performance improvement, but need to pay attention to the hardware differences, the good hardware may not be able to detect the lag or other performance problems. For example, in the process of developing small programs, the simulator is located on the desktop, so its hardware performance is better, such as CPU and GPU. However, once it is run on the mobile terminal, such as ios or Android, performance problems may occur because the hardware condition of the mobile terminal is inferior to that of the PC terminal.

So, performance issues are always there, but hardware differences have different levels of performance impact.

So let’s go back and figure out the solution to cSS3 animation lag: When using CSS3 transtion, choose transform first and avoid height, width, margin and padding.

That’s it !


Why is transform smoother?

The advantage of synthesizer is that its work has nothing to do with the main thread, synthesizer thread does not need to wait for style calculation or JS execution, that is why synthesizer related animation is the most fluent, if an animation involves adjustment of layout or drawing, it will involve the recalcalculation of the main thread, naturally will be a lot slower.

Good quote from infoQ: The most complete article ever! Illustrate how a browser works

When cSS3 transtion is used to animate the transform, the animation implemented by the transform is related to the synthesizer thread. There is no need to wait for the main thread style calculation or JS execution. The calculation speed is very fast. Using height, width, margin, and padding will result in layout and drawing changes, and the main thread will need to recalculate the style and execute JS, which will naturally slow down the calculation.

Reference: sy – tang. Making. IO / 2014/05/14 /… Jinlong. Making. IO / 2017/05/08 /… Blog.csdn.net/yeana1/arti… www.jianshu.com/p/b70b72de3… Developers.google.com/web/tools/c… Blogs.adobe.com/webplatform…

I am looking forward to communicating with you and making progress together. Welcome to join the technical discussion group I created which is closely related to front-end development:

  • SegmentFault column: Be a good front-end engineer while you’re still young
  • Zhihu column: Be an excellent front-end engineer while you are still young
  • Github blog: Personal blog 233 while You’re Still Young
  • excellent_developers

Strive to be an excellent front-end engineer!