你真的了解CSS3硬件加速吗?

常听人说:

移动端要想动画性能流畅,应该使用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技术内幕》这本书。浏览器内核之于前端工程师,就如同操作系统之于后端工程师,毕竟是我们程序运行的宿主环境,多了解一些,很多问题容易想通。

时间: 2024-08-03 13:44:57

你真的了解CSS3硬件加速吗?的相关文章

IE9浏览器无法开启GPU硬件加速?

GPU硬件加速作为IE9浏览器最吸引眼球的功能,各大浏览器也相续的引进这个功能.很多用户也想体验一下这个功能能够给浏览器性能带来多大的提升.但安装了IE9 beta版以后发现无法开启GPU硬件加速,"使用软件呈现,而不使用GPU呈现"的选装怎么都无法取消.该用户的计算机显卡是Intel GMA 3150,使用Windows 7自带的驱动不行,到Intel官网下载使用最新驱动也不行,这个是什么原因呢? 要想体验IE9浏览器的这个功能,对计算机硬件也有一定要求的,IE9的硬件加速需要支持D

GPU硬件加速下Silverlight超性能动画实现(下)

通过上一节的测评,相信大家已经对Silverlight中利用GPU硬件加速来提升性能有了深刻印象. Silverlight游戏开发中,我们需要综合运用多种形式的动画及相关图形处理技巧,此时如果能充分合理的利 用GPU硬件加速功能,配合上性价比最高的功能实现方式,这将为大家打造帝王级高性能RIA网页游戏奠定坚实 的基础. 游戏中的主角是精灵,出现得最多最频繁的同样是精灵:于是,我在上一节的基础上重新修改并制作了全 新的Demo.该Demo中集合了目前主流的Silverlight游戏精灵配置环境,以

GPU硬件加速下Silverlight超性能动画实现(上)

Silverlight3发布时,我和朋友都为其新增的GPU硬件加速功能激动不已,于是开始了肆无忌惮的连夜测试 ,可结果却实在让我们大失所望.是的,不论怎样修改代码都无法感觉到明显的性能提升.接下来的日子里, GPU这个词渐渐的远离了我的脑海.直至几天前,在与一位朋友交流后又再次让我萌生去测试GPU硬件加速在 Silverlight4中效果的想法.真乃不测不知道,一测吓一跳.在最近Silverlight贬低声此起彼伏的日子里, 我相信这篇文章及测试结果必将成为Silverlight开发中最为强劲的

Opera 21支持硬件加速与URL地址完整显示

今天Opera发布了Windows和Mac平台的Opera 21 FINAL网页浏览器,这个版本比较值得一说的改变在于Aura技术的采用--Aura为浏览器提供了硬件加速渲染:此外Opera开发团也针对Opera 21做出了更多合理的优化. 在Opera 21中采用Aura带来的变化在于更刘流畅的使用体验,以及更出色的动画效果.团队在这个版本的Opera浏览器中初步完成了这一特性的加入,未来的版本还会在性能表现方面进一步做优化.Opera另外指出,Mac版本没有采用Aura,但用到了Apple

Win8系统关闭显卡硬件加速的方法

  Win8系统关闭显卡硬件加速的方法 1.在Win8系统中打开运行对话框,然后输入REGEDIT,打开注册表; 2.接着定位到:HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlVideo{C2016678-61EF-4A63-AEDC-F0E05E68A311}000 (视显卡不同而会不同的); 3.查找Acceleration.Level这一键值,如果其值为0,那么表明其完全启用了显卡加速,在这里我们把值修改为5,表示完全禁用显卡加速; 键值说

Win8系统电脑硬件加速怎么调整?

Win8系统电脑硬件加速怎么调整? 具体步骤如下: 1.开始→运行→输入: dxdiag 回车执行DirectX诊断工具. 2.然后点上面的显示标签directdraw 加速. 3.禁用drect3d 加速 禁用agp 纹理加速 禁用.  

win8系统怎样关闭IE浏览器硬件加速功能?

  win8系统怎样关闭IE浏览器硬件加速功能? 1.使用IE打开一个网页,然后点击右上角"小齿轮"设置图标,并选择"Internet选项"; 2.进入 Internet选项后,点击"高级"标签切换到高级操作模式; 3.在设置列表中找到"使用软件呈现而不使用GPU呈现",将前面打勾,然后点击确定完成设置; 4.通过关闭IE浏览器GPU加速的方法一般都能解决在线视频不正常的现象. windows7教程 windows8教程 wi

通过注册表修改硬件加速

  通过注册表修改硬件加速 关闭硬件加速: 1 @echo off 2 title 关闭DirectDraw 3 mode con:cols=50 lines=12 4 color ff 5 6 echo 正在关闭DirectDraw加速... 7 reg add "HKLM/SOFTWARE/Microsoft/Direct3D/Drivers" /v SoftwareOnly /t REG_DWORD /d 1 /f 0>nul 1>nul 8 reg add &quo

win7显卡硬件加速在哪里设置?

步骤一.在win7的桌面,然后随意点击桌面的空白处,在弹出的菜单栏上选择[个性化],弹出了个性化窗口.如图所示: 步骤二.在弹出的窗口上找到"显示"按钮,点击它,然后在继续下一窗口上点击[调整分辨率]按钮,如图所示: 电脑常识 步骤三.最后打开了屏幕分辨率窗口了,然后我们可以在上面设置分辨率大小,不过现在我们说的不是分辨率的问题,继续点击打开[高级设置]按钮,如图所示: 步骤四.现在弹出了一个新的小窗口,在上面切换到[疑难解答]选项卡,然后窗口上点击[更改设置]按钮即可打开硬件加速窗口