常听人说:

移动端要想动画性能流畅,应该使用3d硬件加速

最近深入了解了一些浏览器内核的细节,感觉这里面其实有坑啊。。。

事情要从最近看的《WebKit技术内幕》说起,第二章介绍了网页的结构,其中提到了Webkit硬件加速的方式,会把需要渲染的元素放到特定的『Composited Layer』中,在chrome的控制台可以这样开启:

选择『Show composited layer borders』以后,就能看到有动画3d变换的元素会被一个黄色的边框圈起来,表示放到了一个新的『复合层(composited layer)』中渲染,大概长这个样子:

蓝色的细线是浏览器渲染时候的『瓦片』,浏览器绘制页面的时候只会绘制可视区域一定范围内的瓦片,以节省性能开销,而黄色的边框框起来的,就代表了这个元素被放到特殊的复合层中渲染,跟主文档不在一个层中

然后我觉得这个视图挺有意思的,就拿来看了一下国内某项目,不看不知道,一看被吓尿:

这个项目什么时候搞成所有元素都用3d加速了?!

仔细排查了这些被框出来的元素,完全没有任何需要复合层渲染的迹象,我真是哔了狗了。。。我开始一个个删除元素,简化代码,很快就发现,原来罪魁祸首在这里:

头部的那个轮播动画元素的存在居然会导致下面所有相对和绝对定位的元素都被放到复合层中。。。

查了一些 资料:

层创建标准

什么情况下能使元素获得自己的层?虽然 Chrome 的启发式方法(heuristic)随着时间在不断发展进步,但是从目前来说,满足以下任意情况便会创建层:

  • 3D 或透视变换(perspective transform) CSS 属性
  • 使用加速视频解码的 元素
  • 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 元素
  • 混合插件(如 Flash)
  • 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
  • 拥有加速 CSS 过滤器的元素
  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)

主要是最后一条,我觉得它的中文翻译不是很准确,原文其实是:

Element has a sibling with a lower z-index which has a compositing layer (in other words the it’s rendered on top of a composited layer)

这句话的意思是,如果有一个元素,它的兄弟元素在复合层中渲染,而这个兄弟元素的z-index比较小,那么这个元素(不管是不是应用了硬件加速样式)也会被放到复合层中。

最可怕的是,浏览器有可能给复合层之后的所有相对或绝对定位的元素都创建一个复合层来渲染,于是就有了上面那个项目截图的那种效果。之前一直奇怪为什么这个页面滚动很卡,明明没有多少DOM,现在看来问题就在这里了!

于是乎我写了一个页面,让大家看看这东西到底有多大威力:

http://fouber.github.io/test/layer/

我在上面这个页面中放置了一个h1标题,应用了translate3d动画,使得它被放到composited layer中渲染,然后在这个元素后面创建了2000个list,每个list中都有一个图片,一个标题和一个日期显示,其中图片和日期显示是绝对定位,父容器li是相对定位,然后,各位可以按照前述的说明打开chrome的『show composited layer borders』选项看看这个页面的内容复合层分布:

就是这个鸟样子,很难想象,这样的页面滚动起来会卡成什么样。我用的是mac机器,快速拖动滚动条chrome已经非常吃力了,然后我写了一个简单的滚动条移动操作:

setInterval('document.body.scrollTop++', 0);

然后用timeline抓一下页面性能:

一次『Composite Layers』的计算居然要 96.206 ms !!这还是在我的mac系统上哦,手机上真的会卡出翔。

我在页面上放置了一个开关『为动画元素设置z-index』,这个checkbox点击之后,会用js给那个动画的h1元素加 position:relative 和 z-index: 1 ,这种做法的原理是人为提升动画元素的z-index,让浏览器知道这个元素的层排序,就不会很傻逼的把其他z-index比它高的元素也弄到复合层中了,看看这个效果:

仅仅给动画元素设置一个高一些的z-index,就能解决这种无厘头增加复合层的问题,略无语。。。搞定之后,再用滚动条移动函数抓一下页面性能:

完全恢复正常了有木有!

大家可以用支持『硬件加速』的『安卓』手机浏览器测试上述页面,给动画元素加z-index前后的性能差距非常明显。

不过也不是所有浏览器都有这个问题,我在mac上的Safari、firefox都没有明显差异,安卓手机上的QQ浏览器好像也正常,猎豹、UC、欧朋、webview等浏览器差距明显,更多测试就靠大家来发现吧。

最后总结一下:

使用3D硬件加速提升动画性能时,最好给元素增加一个z-index属性,人为干扰复合层的排序,可以有效减少chrome创建不必要的复合层,提升渲染性能,移动端优化效果尤为明显。

大家可以现在就排查一下这类问题,尤其是用了轮播、动画loading的页面,出现这问题很常见。另外推荐在追查性能问题的时候打开『show composited layer borders』选项,如果页面有很多黄色的框肯定是不对的。

最后,再次推荐一下《Webkit技术内幕》这本书。浏览器内核之于前端工程师,就如同操作系统之于后端工程师,毕竟是我们程序运行的宿主环境,多了解一些,很多问题容易想通。

参考:V8社区

在Blink和WebKit的浏览器中,某个元素具有3D或透视变换(perspective transform)的CSS属性,会让浏览器创建单独的图层。

我们平常会使用left和top属性来修改元素的位置,但left和top会触发重布局,取而代之的更好方法是使用translate,这个不会触发重布局。

解决浏览器渲染的性能问题时,首要目标就是要避免层的重绘和重排。

你真的了解CSS3硬件加速吗?相关推荐

  1. CSS3开启硬件加速及利弊

    最近了解了一下用css3开启硬件加速的这个功能,不得不感叹浏览器这些东西太神奇了,要不是师兄提起,我根本就不知道居然有这种东西.所以还是要提高一下自己的信息来源渠道的. 巴拉巴拉了一下,下面我们正式来 ...

  2. 硬件加速下webview切换闪屏_网页渲染性能优化 —— 性能优化下

    博客 有更多精品文章哟. Composite 的优化 终于,我们到了像素管道的末尾.对于这一部分的优化策略,我们可以从为什么需要 Composited Layer(Graphics Layer)来入手 ...

  3. CSS动画开启硬件加速

    (一)前言 在需要高频交互的css动画时候,我们就需要考虑使用CSS3 硬件加速. 首先,CSS3 硬件加速又叫做 GPU 加速,是利用 GPU 进行渲染, 减少 CPU 操作的一种优化方案.由于 G ...

  4. 关于硬件加速哪些优秀的资源总结

    问题1:transform动画为什么没有经过大量的重绘? 解答:为什么 transform 没有触发 repaint 呢?(1)简而言之,transform 动画由GPU控制,支持硬件加速,并不需要软 ...

  5. 显示卡影片播放硬件加速,作法原理完全解说

    原文地址:http://www.5i01.cn/newsdetail.php?id=4481 作者:G.F. 我还记得我装第一台电脑时,为了看VCD的....好看影片(羞),还特别去买一张VCD加速卡 ...

  6. css怎么使用gpu加速,用CSS3开启GPU硬件加速来提升网站的动画渲染性能

    CSS3为咱们开发动画效果大大提升了效率,但有些动画效果,如果涉及的DOM元素比较多,会发现有"卡卡"的感觉,为动画DOM元素添加CSS3样式 -webkit-transform: ...

  7. Minimit Anima – 硬件加速的 CSS3 动画插件

    Minimit Anima 是一个实现 CSS3 Transforms 和 Transitions 动画的 jQuery 插件.基于硬件加速的 CSS3 动画执行更快,而且它有一个类似于 jQuery ...

  8. html代码硬件加速优化,详解CSS3开启硬件加速的使用和坑

    前言 最近在看在github上看iscroll的文档.虽然是英文的,但是为了装逼,没办法硬着头皮看完了,觉得作者写得不错(我有那么好耐心写那么长的文档就好了[捂脸]),然后为了更好地装逼,有看了一遍, ...

  9. 使用CSS3开启GPU硬件加速提升网站动画渲染性能

    中文地址:http://www.cnblogs.com/rubylouvre/p/3471490.html 原文地址:http://blog.teamtreehouse.com/increase-yo ...

最新文章

  1. input样式和修改
  2. Windows Server 2003 SP2 R2 企业版/标准版/32与64位 CD-KEY
  3. 机器人动力学(Basic Newton-Euler Mechanics)
  4. Codeforces Round #392(div 2) 758D (贪心)
  5. 新型冠状病毒传染性有多强?何时达到疫情峰值?来看一下数学和统计建模结果...
  6. 在java继承机制中 父类中的私有_Java中子类能继承父类的私有属性吗?
  7. linux查询.gz日志,linux2-查日志
  8. ie6,ie7兼容性总结
  9. c语言全排列库函数,几种全排列的算法(C语言实现)
  10. ubuntu安装中文输入法fcitx
  11. 鼎立td测试软件窗口参数介绍,鼎立网优参数指标解释
  12. 备忘录形成html乱码,浏览器icloud网页版备忘录乱码不能显示中文汉字-企业网站设计之中的字体坑...
  13. 如何在 Visual Paradigm 中创建流程图丨使用教程
  14. 复旦学子《可解释机器学习》中文版火了,完整PDF开发下载!
  15. Java Email Server
  16. 【饭谈】软素质怎么提高?(适合软件测试人的专用办法)
  17. 华南x79主板u盘装系统教程_华南x79主板怎么装win7系统|华南x79主板装win7及BIOS设置...
  18. GEA 3.1 重温C++以及实践
  19. 目标跟踪之LTMU:High-Performance Long-Term Tracking with Meta-Updater环境配置及代码运行
  20. 7月16日数据科学库学习笔记——matplotlib 绘制散点图、条形图、直方图

热门文章

  1. 数据结构学习之路-第一章:绪论
  2. C#为什么要用到 try...catch... 呢?
  3. 输入正方形对角线两个端点坐标,求中点坐标
  4. Scala入门到精通——第二十三节 高级类型 (二)
  5. 聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore
  6. Attention的梳理、随想与尝试
  7. Centos7安装时引导错误以及解决方案
  8. [集合]线程安全的HashMap
  9. Eclipse And Android 使用心得
  10. leetcode-728-Self Dividing Numbers