css硬件加速_CSS动画的硬件加速简介
css硬件加速
In the last couple of years we’ve often heard about hardware acceleration and how it helps to improve animation on web pages, making them nice and smooth even on mobile browsers. But I think a lot of less experienced developers don’t know how hardware acceleration works and how we can use it properly to make our animations shine.
在过去的两年中,我们经常听到有关硬件加速及其如何帮助改善⽹页动画的信息,即使在移动浏览器上也能使它们流畅流畅。 但是我认为许多经验不⾜的开发⼈员都不知道硬件加速是如何⼯作的,以及如何正确使⽤它来使动画发光。
The term itself sounds like something overly complicated, close to higher mathematics. In this article, I’ll shed some light on this subject and demonstrate how to utilize this technique in your front-end projects.
这个词本⾝听起来有点过于复杂,接近于⾼等数学。 在本⽂中,我将对此主题进⾏⼀些说明,并演⽰如何在前端项⽬中利⽤此技术。
我为什么要在乎? (Why Should I Care?)
Let’s look at a simple animation example containing several balls stacked on top of one another (that is, on the z-axis, so it looks like one ball). The goal is to move this group of balls with animation. The easiest way to do this is to adjust the left and top properties. We could do this with JavaScript, but we’ll use CSS animations instead. Please note that I’m excluding any vendor prefixes but you should use something like to ensure full compatibility.
让我们看⼀个简单的动画⽰例,其中包含多个相互叠放的球(即,在z轴上,因此看起来像⼀个球)。 ⽬标是通过动画移动这组球。 最简单的⽅法是调整left和top属性。 我们可以使⽤JavaScript来做到这⼀点,但是我们将改⽤CSS动画。 请注意,我不包括任何供应商前缀,但是您应该使⽤诸如类的以确保完全兼容。
.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;
}
}
Here is a live demo that uses a button to initiate the animation with JavaScript:
这是⼀个实时演⽰,该演⽰使⽤按钮来启动JavaScript动画:
See the Pen by SitePoint () on .
请参见上的 ( )的的Pen 。
After clicking the “Start Animation” button, you’ll notice that the animation doesn’t look very smooth, e
ven on a desktop browser. If you test the animation on your mobile device, you’ll see that it’s far from 60fps. To fix this, we can use CSS transform using the translate() function, instead of animating the top and left values.
单击“开始动画”按钮后,您会注意到,即使在桌⾯浏览器上,动画看起来也不是很平滑。 如果您在移动设备上测试动画,则会发现它与60fps的差距很⼤。 为了解决这个问题,我们可以使⽤带有transform translate()函数CSS变换,⽽不是对top和left值进⾏动画处理。
.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);
}
}
Try the above code in the demo below:
在下⾯的演⽰中尝试上⾯的代码:
See the Pen by SitePoint () on .
请参见上的 ( ) 的Pen 。
Now the animation is nice and smooth. Great! So why did this help? Well, CSS transforms don’t cause repaints, unlike animations with the left and top properties. Let’s look at the Timeline panel in Chrome’s DevTools during the animation execution:
现在,动画变得流畅流畅。 ⼤! 那为什么有帮助呢? 嗯,与具有left和top属性的动画不同,CSS转换不会导致重新绘制。 在动画执⾏期间,让我们看⼀下Chrome开发⼈员⼯具中的“时间轴”⾯板:
In the left and top example, we can see green bars at each animation step. This is an expensive repainting operation. The animation frame rate is less than 60fps, which we always aim at achieving to make the animation smooth.
在left和top⽰例中,我们可以在每个动画步骤中看到绿⾊的条。 这是昂贵的重涂操作。 动画帧率⼩于60fps,我们⼀直致⼒于使动画流畅。
Now look at the timeline in the case of CSS transforms:
canvas动画现在来看⼀下CSS转换的时间轴:
As you can see, there are no green bars during the animation.
如您所见,动画过程中没有绿⾊条。
Another feature available in Chrome’s DevTools to track the repainting process is “Enable paint flashing”. You can find this option by opening the DevTools, hitting the ESC key, then choosing the “Rendering” tab. When this feature is turned on, green boxes (i.e. paint rectangles) will appear around repainted areas. In the left and top example, the balls have a green box for the entire animation process, indicating the repaints.
Chrome的DevTools中可⽤来跟踪重新绘制过程的另⼀个功能是“启⽤绘制闪动”。 您可以通过打开DevTools,按ESC键,然后选
择“渲染”选项卡来到此选项。 启⽤此功能后,重新绘制区域周围将出现绿⾊框(即绘制矩形)。 在left和top⽰例中,球在整个动画过程中都有⼀个绿⾊框,指⽰重新绘制。
On the other hand, in the CSS transforms example, the paint rectangle is displayed only on the first and last animation frames.
另⼀⽅⾯,在CSS转换⽰例中,绘制矩形仅显⽰在第⼀个和最后⼀个动画帧上。
So how exactly do transforms render the animation without repaints? The basic answer is that CSS transforms occur directly in the GPU memory that utilizes hardware acceleration, which avoids software rendering. Let’s look at this in more detail.
那么,变换如何准确地渲染动画⽽不重绘呢? 基本答案是CSS转换直接在利⽤硬件加速的GPU内存中发⽣,从⽽避免了软件渲染。 让我们更详细地看⼀下。
硬件加速如何⼯作 (How Hardware Acceleration Works)
When the browser receives a page’s markup, it parses it to build the DOM Tree. The DOM Tree and CSS allow the browser to build the Render Tree. The Render Tree consists of render objects – the elements to be rendered on the page. Each render object is assigned to a graphic layer. Each layer is uploaded to GPU as a texture. The trick here is that the layer may be transformed in the GPU without repainting, like in the case of 3D graphics. These transformations are made by the separate Compositor process. You can find more information about .
当浏览器收到页⾯的标记时,它将对其进⾏解析以构建DOM树。 DOM树和CSS允许浏览器构建渲染树。 渲染树由渲染对象(即要在页⾯上渲染的元素)组成。 每个渲染对象都分配给⼀个图形层。 每层都作为纹理上传到GPU。 这⾥的窍门是可以像不使⽤3D图形⼀样在GPU上变换图层⽽⽆需重新绘制。 这些转换是通过单独的合成器过程进⾏的。 您可以到有关更多信息。
In our example, the CSS transform creates a new composite layer that can be transformed directly in the GPU. Chrome’s DevTools allow for viewing composite layers using the “Show layer borders” opti
on. Each composite layer has an orange border.
在我们的⽰例中,CSS转换创建了⼀个新的复合层,可以直接在GPU中对其进⾏转换。 Chrome的DevTools允许使⽤“显⽰图层边框”选项查看复合图层。 每个复合层都有⼀个橙⾊边框。
Our balls with the CSS transformation have orange borders and are moved to separate composite layers:
我们CSS转换球具有橙⾊边框,并移⾄单独的复合层:
At this point, you might ask: When does a browser create a separate composite layer?
此时,您可能会问:浏览器何时创建单独的复合层?
It does so in the following cases:
在以下情况下会这样做:
For 3D or perspective CSS transforms (in our example)
对于3D或透视CSS转换(在我们的⽰例中)
For <video> or <canvas> elements
对于<video>或<canvas>元素
When using CSS filters
使⽤CSS过滤器时
For an element that overlaps another element extracted to a composite layer (e.g., using z-index)
对于与另⼀个提取到复合层的元素重叠的元素(例如,使⽤z-index )
You might be thinking, ‘Hold on. This example used 2D translation, not 3D transforms’. And you’re right. That’s why there are two extra repainting operations – at the start and end of the animation process in our timeline.
您可能会想,“等等。 此⽰例使⽤2D翻译,⽽不是3D变换。 ⽽且你是对的。 这就是为什么在时间轴的动画过程的开始和结束时要进⾏两个额外的重新绘制操作的原因。
The difference between the 3D and 2D transforms is that 3D transforms make the browser create a separate composite layer beforehand, while 2D transforms do it on the fly. At the start of the animation, a new composite layer is created and the textures are loaded to the GPU, which initiates the repainting. Then the animation is performed by the Compositor in the GPU. When the animation is finished, the additional composite layer is removed, which results in another repainting operation.
3D转换和2D转换之间的区别在于3D转换使浏览器预先创建⼀个单独的复合层,⽽2D转换则是即时进⾏。 在动画开始时,将创建⼀个新的复合层,并将纹理加载到GPU,从⽽启动重新绘制。 然后,动画由GPU中的合成器执⾏。 动画结束后,附加的复合层将被删除,这将导致另⼀个重新绘制操作。
GPU中的渲染元素 (Rendering Elements in the GPU)
Not all CSS property changes on elements can be handled directly in the GPU. Only the following properties are supported:并⾮所有元素上CSS属性更改都可以直接在GPU中处理。 仅⽀持以下属性:
transform
transform
opacity
opacity
filter
filter
And so to ensure the best chance for a smooth, high-quality animation, we should always try to use these GPU-friendly properties.
因此,为了确保获得流畅,⾼质量动画的最佳机会,我们应该始终尝试使⽤这些对GPU友好的属性。
强制在GPU中渲染元素 (Forcing an Element to Be Rendered in GPU)
In certain cases, it may be required to render an element in the GPU even before the animation has begun. This helps avoid the first repainting operation caused by the new layer creation. To achieve this, the so called “transform hack” may come in handy.
在某些情况下,甚⾄在动画开始之前,可能仍需要在GPU中渲染元素。 这有助于避免由新图层创建引起的第⼀次重绘操作。 为了实现这⼀点,所谓的“转换hack”可能派上⽤场。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论