此文已由作者袁申授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

有数的数据大屏可以在一块屏幕上展示若干张不同的图表,以炫酷的方式展示各种业务数据。其中有些图表使用CSS实现了饼图轮播、地图标记点闪烁等动画,然而在一张大屏上同时显示了许多张图表时,持续的动画效果有时会出现掉帧、卡顿的情况,需要对动画性能进行优化。本文简单介绍了chrome浏览器性能分析工具和CSS动画使用GPU加速进行性能优化的解决方案。

浏览器渲染流程

这是浏览器渲染引擎的处理过程:

接收到文档后,渲染引擎会对HTML文档进行解析生成DOM树、对CSS文件进行解析生成CSSOM树;同时执行页面中的JavaScript代码;最终根据DOM树和CSSOM树,计算样式(Caluclate Style)生成渲染树,渲染树中,只会包含即将显示在页面中的元素及其样式信息(如head元素、display为hidden的元素就不会包含在渲染树中);根据渲染树需要进行布局(layout)来计算每个元素在页面上的位置;

接下来渲染引擎开始进行绘制(paint),这一步分为若干阶段:根据渲染树将每层(layer)的各个元素绘制,然后将绘制出的若干连续图像进行栅格化(Rasterization),最后将栅格化后的图像合成(composite)为要显示在屏幕上的图像。对每一层的绘制是由浏览器来完成的;最后的合成是由GPU来完成;而栅格化过程取决于浏览器的设置,chrome默认开启GPU栅格化,否则由CPU进行。

当首次将DOM树构建完成后,每次页面发生改变时进行进行的主要流程为:

其中CSS动画不会调用JavaScript,我们知道,在渲染中主要消耗时间的是Layout/Reflow和Paint/Repaint的过程,因此要尽量避免和减少这两个阶段的时间。

影响CSS动画性能的因素

这是一个CSS动画,控制一个方块的top、left属性实现平移。使用Chrome提供的浏览器性能分析工具分析动画的性能,打开浏览器开发者工具后,在标签中选择performance打开性能分析面板。在性能分析面板中对当前页面进行录制,录制结束后分析结果中可以查看页面在这段时间内的FPS、CPU占用等情况,在main中包含了浏览器的渲染流程,包括Scripting、Rendering、Painting等。

执行这个CSS动画时,不涉及JavaScript的调用;紫色部分是render,依次分别为Recaculate Style、Layout和Update Layer Tree;绿色部分为Painting,依次分别为Paint和Composite Layers。

在下面的面板中也可以查看当前时间段内各个阶段执行时间

more tools中的rendering也包含若干查看渲染有关的选项:

勾选paint flashing,页面上会以绿色方块显示需要重绘的区域,当前小方块进行了平移,因此需要重绘;勾选layer borders,会以黄色方框显示页面的分层情况,此时页面只有一个层,蓝色的线显示了tile的划分,它是一个layer中的分块;FPS meter可以显示页面的FPS、是否使用GPU进行栅格化过程和GPU显存使用情况,由于默认开启了GPU栅格化,GPU Raster显示为on:

more tools中的layers可以查看页面分层,以及每层的详细信息等:

通过对这些数据我们可以对页面加载的性能瓶颈进行分析和针对性的优化。

使用GPU加速

浏览器的GPU加速功能是将需要进行动画的元素提升到一个独立的层(layer),这样就可以避免浏览器进行重新布局(Reflow)和绘制(Repaint),将原先的浏览器使用CPU绘制位图来实现的动画效果转为让GPU使用图层合成(composite)来实现,如果两张图层内部没有发生改变,浏览器就不再进行布局和绘制,直接使用GPU的缓存来绘制每个图层,GPU只负责将各个图层合成来实现动画,这就可以充分利用GPU的资源和优势,减轻CPU的负载,可以使动画更流畅。通过改变两张图片之间的相对位置代替绘制一张图片的每一帧来实现动画,虽然视觉效果相同,但省去了许多绘制的时间。

为了让浏览器将动画元素提升到一个独立的层,可以使用transform和opacity属性来实现动画,当设置了这两个属性之一时,浏览器会自动进行这一优化操作(透明度的变化可以通过GPU改变a通道来实现,不需要浏览器进行重绘)。对于上面的动画,可以改变transform来代替改变left和top属性:

这个动画进行分析,可以看到使用transform后浏览器为小方块单独设置了一个层,并且不再触发浏览器更新样式:

如果动画并不需要对transform和opacity属性做出改变,可以使用其他的方法强制浏览器为这些元素创建单独的层,比如设置一个没有效果的样式:transform:translateZ(0);这不会对元素的实际样式做出改变。但这是一种hack,规范的做法是使用will-change属性,设置它的值为需要做变换的属性,如will-change: left;浏览器就会知道left这个属性会发生变化,因此会开启硬件加速优化性能。

这是使用will-change属性的平移动画,同样也为小方块设置了单独的图层。

避免过度绘制

既然设置了will-change属性可以开启GPU加速,那么:

* {  will-change: all;}

看起来好像是一劳永逸的方法,但其实这反而会降低页面的性能,虽然硬件加速可以提高GPU的使用,但从layers中的信息可以看出,每个层都需要消耗一定的内存,过多的内存占用也会造成性能的下降;过多的层传输到GPU的过程也会消耗一定的时间,此外也造成合成阶段的时间占用较长,因此并不是独立的层越多越好。最好的做法是对那些可能动画的元素设置属性,并在动画结束后就移除这个属性。

SVG图表动画性能的优化

根据以上的分析,总结GPU实现动画的优缺点:

优点:

  • 利用了GPU合成图层实现动画,可以做到动画平滑、流畅

  • 动画合成工作在GPU线程,不会被CPU的js运行阻塞

缺点:

  • 绘图层必须传输到GPU,当图层较多时传输过程可能会导致渲染缓慢

  • 每个复合层都需要消耗额外的内存,过多的内存可能导致浏览器的崩溃

  • 复合层合成需要更多的时间

对于一般的HTML的元素,遵循上述的方法就可以了,但有数大屏中的图表是使用SVG元素来绘制的,由于并不是标准的DOM元素,Chrome并不能支持SVG元素的硬件加速,即使设置了transform、will-change等属性,单个的SVG元素也不能作为单独的层进行绘制。

从这个使用transform实现的SVG动画可以看到即使使用了transform,动画部分的页面仍然需要重绘。

对于下面这个有多个图表的页面,其中只有一个图表有动画,在动画过程中,如果只有一个图层,那么需要将整个图层进行重绘,虽然现在Chrome已经可以智能选择最小的重绘区域进行增量绘制,但当图层较大时这样的判断也会造成一定的开销。因此可以考虑将有动画的图标单独放在一个图层中,其他没有动画的图表和页面是的其他元素仍然和背景在一个图层中:

分别对分层的和未分层的页面进行5次性能测试,将分析结果进行对比:

可以看出,分层后每帧动画绘制的总时间有明显下降,主要体现在绘制(painting)过程中:其中paint时间的减少应该是因为每次重绘的图层面积只有图表区域,因此需要更少的时间来判断需要更新纹理的区域;composite layers时间的减少,应该主要是由于需要绘制的图层的减小,导致纹理上传GPU和调用OpenGL绘制接口的时间减少了;而rendering时间的增加原因还需要进一步的调研。

在实际使用中,可以在某张图表需要动画时,设置SVG标签的will-change属性,将SVG元素提升到独立的层,来减少动画绘制时间;而图表没有动画时则不需要特别处理,避免过度绘制造成的内存占用增加和图层传输、合成时间的增加。

参考

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 用script标签加载

CSS动画的性能分析和浏览器GPU加速的更多相关文章

  1. css动画属性性能

    性能主要表现:流量.功耗与流畅度 在现有的前端动画体系中,通常有两种模式:JS动画与CSS3动画. JS动画是通过JS动态改写样式实现动画能力的一种方案,在PC端兼容低端浏览器中不失为一种推荐方案. ...

  2. CSS动画属性性能详细介绍

    CSS动画属性会触发整个页面的重排relayout.重绘repaint.重组recomposite Paint通常是其中最花费性能的,尽可能避免使用触发paint的CSS动画属性,这也是为什么我们推荐 ...

  3. Android性能分析工具Profile GPU rendering详细介绍

    如何在一个应用中追踪和定位性能问题,甚至在没有它的源代码的情况下?? “Profile GPU rendering”(GPU渲染分析),一款Android4.1所引入的工具.你可以在“设置”应用的“开 ...

  4. 盒子端 CSS 动画性能提升研究

    不同于传统的 PC Web 或者是移动 WEB,在腾讯视频客厅盒子端,接大屏显示器(电视)下,许多能流畅运行于 PC 端.移动端的 Web 动画,受限于硬件水平,在盒子端的表现的往往不尽如人意. 基于 ...

  5. 前端性能优化之利用 Chrome Dev Tools 进行页面性能分析

    背景 我们经常使用 Chrome Dev Tools 来开发调试,但是很少知道怎么利用它来分析页面性能,这篇文章,我将详细说明怎样利用 Chrome Dev Tools 进行页面性能分析及性能报告数据 ...

  6. GPU—加速数据科学工作流程

    GPU-加速数据科学工作流程 GPU-ACCELERATE YOUR DATA SCIENCE WORKFLOWS 传统上,数据科学工作流程是缓慢而繁琐的,依赖于cpu来加载.过滤和操作数据,训练和部 ...

  7. 构建可扩展的GPU加速应用程序(NVIDIA HPC)

    构建可扩展的GPU加速应用程序(NVIDIA HPC) 研究人员.科学家和开发人员正在通过加速NVIDIA GPU上的高性能计算(HPC)应用来推进科学发展,NVIDIA GPU具有处理当今最具挑战性 ...

  8. Android 常用的性能分析工具详解:GPU呈现模式, TraceView, Systrace, HirearchyViewer(转)

    此篇将重点介绍几种常用的Android性能分析工具: 一.Logcat 日志 选取Tag=ActivityManager,可以粗略地知道界面Displaying的时间消耗.当我们打开一个Activit ...

  9. CSS动画与GPU

    写在前面 满世界的动画性能优化技巧,例如: 只允许改变transform.opacity,其它属性不要动,避免重新计算布局(reflow) 对动画元素应用transform: translate3d( ...

随机推荐

  1. iOS之简单瀑布流的实现

    iOS之简单瀑布流的实现   前言 超简单的瀑布流实现,这里说一下笔者的思路,详细代码在这里. 实现思路 collectionView能实现各中吊炸天的布局,其精髓就在于UICollectionVie ...

  2. 怎样得到QML package的具体API接口

    虽然我们的developer站点有丰富的API介绍,可是,有些API的介绍可能并不全,有些API也在不断地演进中. 为了得到更具体的API,我们能够通过例如以下的命令来得到更加具体的信息.比方我们对& ...

  3. ASP.NET MVC EXTJS 通用主菜单框架

    一.说明 首先我不知道定义的文章标题是不是准确,我这篇博文介绍的是一个通用的软件主菜单框架,界面布局用的是extjs,还是先上一个图吧. 软件主界面左侧菜单采用的风格是extjs的手风琴模式,需要注意 ...

  4. 为自己编写的windows应用程序制作安装包

    1 写好了一个windows程序之后如何制作安装包 这个在vs中就可以直接发布了,可以制作msi的安装包和exe的安装包. 2 window应用程序安装包做了哪些事情 rpm安装包的话,只是把相应的文 ...

  5. Embed image in a <button> element 微信小程序 客服按钮

    html - Embed image in a <button> element - Stack Overflow https://stackoverflow.com/questions/ ...

  6. swift-ios开发pod的使用(1)

    MAC安裝CocoaPods   http://www.cnblogs.com/surge/p/4436360.html 请注意我的环境,这个很重要 xcode版本7.3.2   mac 版本OS X ...

  7. smod包含具体的增强(具体实施对象) / CMOD 包含一组smod编写的增强

    从标题来看,CMOD 是树木,smod 是树枝. 1.1 SMOD包含具体的增强,而CMOD是包含一组SMOD编写的增强. 1.2 User exits (Function module exits) ...

  8. (转)基于RTP的H264视频数据打包解包类

    最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包.解包的文档和代码.功夫不负有心人,找到不少有价值的文档和代码.参考这些资料,写了H264 RTP打包类.解包类,实现 ...

  9. ubuntu动态加载模块简单模板

    1:简单代码 #include<linux/init.h> #include<linux/module.h> MODULE_LICENSE("GPL"); ...

  10. oracle rac常用的网络检查命令

    oracle的集群管理软件和数据库对私网依赖性很大,很多集群问题最后都可以归结到网络层面. 当集群出现问题时检查网络信息是必要的. 1.查看MTU的大小,确认所有节点的公网和私网网卡的MTU大小相同 ...