In a recent project, due to the lack of good planning at the initial stage and the limited technical ability of the staff, there were many problems in performance, and my main task in this project was to optimize various performance. Among them, there are more optimization related to rearrangement, redrawing and hardware acceleration. This optimization method has low cost, low risk and obvious effect on poorly configured devices. Here is a link to the original article

In recent years, we’ve been hearing a lot about hardware acceleration and how it’s helping us make web animation better and smoother on mobile. But I think a lot of inexperienced engineers don’t know how hardware acceleration works and how we use it to help us make animations smoother.

Hardware acceleration sounds very complex, like advanced mathematics. In this article, I will briefly explain how to use this technology in your front-end engineering.

Why is it needed?

Let’s look at a simple animation example of some balls superimposed on top of each other. And then you move this set of balls along a quadrilateral trajectory. The easiest way to do this is to set left and top. We can do it in JavaScript, but we’re going to do it in CSS. Note that I did not use any auxiliary libraries, such as Autoprefixer, but I recommend that you use such libraries in your projects to automatically replenish prefixes

.ball-running {
  animation: run-around 4s infinite;
}

@keyframes run-around {
  0%: {
    top: 0;
    left: 0; 25%} {top: 0;
    left: 200px; 50%} {top: 200px;
    left: 200px; 75%} {top: 200px;
    left: 0; }}Copy the code

Here’s an online example. Run JavaScript to launch an animation with a button:

CodePen Preview for Animating overlapping balls with top/left Properties

Click on “Start Animation” and you’ll notice that animations don’t run smoothly in any desktop browser. If you run the animated web page on mobile, you will see a significant loss of frames. To solve this problem, we can use the transform translate() function instead of the changes to left and top.

.ball-running {
  animation: run-around 4s infinite;
}

@keyframes run-around {
  0%: {
    transform: translate(0, 0); 25%} {transform: translate(200px, 0); 50%} {transform: translate(200px, 200px); 75%} {transform: translate(0, 200px); }}Copy the code

Try running the above code in the following example:

Animating overlapping balls with CSS transforms

Animation is much smoother now than before. Very good! So why is this? Ha, the CSS transform does not cause a redraw like the left and top properties. Let’s take a look at the execution results of the Timeline page in DevTools in Chrome.

In the left and top examples, we can see that there are green bars at each step. This is a high performance cost operation. Animation can cause frame loss, which is the standard for optimizing animation effects.

Items to see the timelines for CSS Transforms:

As you can see, there are almost no green bars.

Another tool for tracking redrawing processing is the Enable Paint flashing option in Rendering in Chrome’s DevTools. When this option is selected, the green box will appear in the redrawn area. In the left and top examples, the ball has a green box when the animation is running, so the ball is redrawn.

In another example, the redraw only happens at the beginning and end of the animation.

So how does Transform make animations not cause redraws? The immediate answer is that Transform will use hardware acceleration directly and run on the GPU, bypassing software rendering.

How does hardware acceleration work

When the browser receives a page, it interprets the page as a DOM input. DOM trees and CSS let the browser build the render tree. The render book contains render objects – elements in the page that need to be rendered. Each rendered object is assigned to a layer. Each layer is updated to the GPU. The secret here is that the layers through Transform are rendered using the GPU and therefore do not need to be redrawn, just like 3D graphics. This transformation is handled separately.

In our example, the CSS Transform creates a new layer directly on the GPU. The “Show Layer Borders” option in Chrome’s DevTools will help you see which layers are individual. When this option is turned on, individual layers will have an orange border.

A transform ball is surrounded by an orange border, so it’s in a separate layer:

At this point, you may be asking: When will browsers create this separate layer?

New layers are created in the following cases:

  • 3 d orCSSthetransformattribute
  • <video><canvas>The element
  • CSSthefilterattribute
  • An element that overlays another element, such as byz-indexImprove level

You might be thinking, ‘Wait a minute, this is a 2D conversion, not a 3D conversion’. Yes. That’s why there are two redraws at the beginning and the end.

The difference between 3D and 2D conversions is whether the new layer is generated in advance, and in the case of 2D, at the time of execution. At the beginning of the animation, a new layer is created and passed to the GPU for processing. When the animation is over, the individual layers are removed and the result is redrawn.

inGPURender elements

Not all CSS property changes are processed directly on the GPU. Only the following properties are treated like this:

  • transform
  • opacity
  • filter

Therefore, in order to make the page more smooth and high-performance animation, we need to use GPU processing as much as possible.

Mandatory inGPUApply colours to a drawing

In some cases, it will attempt to render an element on the GPU at the beginning of the animation. This will help us avoid redrawing when creating a new layer. Therefore, we need to use transform hack technology

.example1 {
  transform: translateZ(0);
}

.example2 {
  transform: rotateZ(360deg);
}
Copy the code

Doing so will let the browser know that we want to do the conversion in 3D, which will allow the browser to use the GPU processing from the very beginning, enabling hardware acceleration.

This technique can also be applied to complex elements. Let’s go back to the first example and change the example to include a ball and use the filter attribute and a container with a background image. The ball is animated by left and top.

Animating a ball with top/left properties

Again, the animation starts to lose frames. Because each redraw results in a significant performance cost.

Now let’s add the transform hack.

Animating left/top properties with hardware acceleration

It’s not as bad as it used to be. Why is that? Because the background is now treated in a separate layer, the cost of repainting is much lower.

Some considerations when using hardware acceleration

There is no free lunch. There are several problems with hardware acceleration.

Memory

Most of the important questions are about memory. Processing too much content on the GPU can cause memory problems. This causes crashes on mobile and mobile browsers. Therefore, hardware acceleration is usually not used for all elements.

Font rendering

Rendering fonts on the GPU will invalidate anti-aliasing. This is because the GPU and CPU have different algorithms. So if you don’t turn off hardware acceleration at the end of the animation, the font will blur.

The Near Future

Where it’s necessary to use a Transform hack is to improve performance. The browser itself also provides an optimized feature, which is the will-change property. This feature allows you to tell the browser that the property will change, so the browser will optimize it before it starts. Here’s an example:

.example {
  will-change: transform;
}
Copy the code

Unfortunately, not all browsers support this feature.

At the end of the article

Here’s an overview of what we’ve been talking about:

  • GPURendering can improve animation performance
  • GPURendering increases the number of frames rendered for the animation
  • Use can lead toGPUrenderingCSSattribute
  • Understand how to force an element in a “transform hack”GPUApply colours to a drawing