GPU加速
大多数设备的刷新频率是60次/秒,(1000 / 60 = 16.6ms)也就是说浏览器对每一帧的渲染工作要在16ms内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。
浏览器在每一帧里面,会依次执行以下动作: js -> style -> layout ->paint -> composite。
1. js: js实现动画效果,DOM元素操作等。
2. style(计算样式): 确定每个DOM元素在最终屏幕上显示的大小和位置。由于web页面的元素布局是相对的,所以任意一个元素的位置发生变化,都会联动的引起其他元素变化,这个过程叫做reflow。
3. paint(绘制):在多个层上绘制DOM元素的文字,颜色,图像,边框和阴影等。
4. composite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。
减少或者避免layout和paint,可以让页面不卡顿,动画效果更加流畅。利用GPU加速优先使用渲染层,避免layout和paint。
通过改变元素的transform实现移动,伸缩变化而非改变物体的left,top,width,height避免layout和paint。
.state1 {
top: 10px;
}
.state2 {
top: 30px;
}
可以优化成为
.state1 {
transform: translateY(10px);
}
.state2 {
transform: translateY(30px);
}
GPU是什么
gpu的过程是以下这几步
1. 获取DOM并将其分割成多个层(renderLayer)
2. 将每个层栅格化,并独立的绘制进位图中
3. 将这些位图作为纹理上传至GPU
4. 复合多个层来生成最终的屏幕图像(最后的layer)
我们只需要知道开启了GPU加速的元素被独立出来,不会再影响其他dom的布局,因为它改变之后,只是相当于被贴上了页面
我们可以通过chrome浏览器上的more tools的rendering查看renderLayer,黄色栅格代表开启了GPU加速的元素,蓝色栅格可以看作是比层第一级的renderLayer
如何开启GPU加速
目前下面这些因素都会引起chrome创建合成层
1. 3D或者透视变化(perspective ,transform)属性
2. 使用加速视频解码的video元素
3. 拥有3D(WebGL) 上下文或加速的2D上下文的canvas元素
4. 混合插件(如flash)
5. 对元素的opacity做CSS动画或使用一个动画webkit变换的元素
6. 拥有加速CSS过滤器的元素
7. 元素A有一个z-index比自己小的元素B,且元素B在一个合成层上渲染(也就是开启了GPU加速),则元素A会提升成合成层
GPU加速的坑
主要问题出在上述的第7点。如果把z-index比GPU加速元素高的元素都放到合成层中,就会创建不必要的合成层影响性能。我们可以通过给动画元素增加一个高一点的z-index属性,人为干扰复合层,提高渲染性能。
重绘(redraw)和重排(reflow)
重绘:是一个元素的外观变化所引发的浏览器行为;例如改变visibility、outline、背景色等属性。
重排:是引起DOM树重新计算的行为。当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。
如果没有开启GPU加速,那么只有opacity和transform的动画不会引起CPU的重排(需要CPU参与),只会执行重绘。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/13500.html