1. chrome Layer borders

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



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

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

2. 层创建标准

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

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

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

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

查了一些 资料:

层创建标准

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

1、3D 或透视变换(perspective transform) CSS 属性

2、使用加速视频解码的 元素

3、拥有 3D (WebGL) 上下文或加速的 2D 上下文的 元素

4、混合插件(如 Flash)

5、对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素

6、拥有加速 CSS 过滤器的元素

7、元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)

8、元素有一个 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,现在看来问题就在这里了!

3. 例子

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

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』选项,如果页面有很多黄色的框肯定是不对的。

转:CSS3硬件加速也有坑!!!

3D硬件加速提升动画性能 与 z-index属性的更多相关文章

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

    遇到的问题: 网站本身设计初衷就没有打算支持IE8及以下版本浏览器,并不是因为代码兼容性问题,而是真的不想迁就那些懒得更新自己操作系统和浏览器的用户,毕竟是我自己的网站,所以我说了算!哈哈~ 没有了低 ...

  2. CSS开启硬件加速提高网站性能

    国外一篇文章,有点意思,转载过来,准备尝试下~ 中文地址:http://www.cnblogs.com/yzw7489757/ 原文地址:http://blog.teamtreehouse.com/i ...

  3. 使用css来开启硬件加速来提高网站性能

    一.什么是硬件加速 硬件加速就是将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器,这样就可以使得animation与transition更加顺畅.我们可以在浏览器中用css开启硬件加速 ...

  4. GPU硬件加速原理 /转

    现代浏览器大都可以利用GPU来加速页面渲染.每个人都痴迷于60桢每秒的顺滑动画.在GPU的众多特性之中,它可以存储一定数量的纹理(一个矩形的像素点集合)并且高效地操作这些纹理(比如进行特定的移动.缩放 ...

  5. GPU硬件加速

    现代浏览器大都可以利用GPU来加速页面渲染.每个人都痴迷于60桢每秒的顺滑动画.在GPU的众多特性之中,它可以存储一定数量的纹理(一个矩形的像素点集合)并且高效地操作这些纹理(比如进行特定的移动.缩放 ...

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

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

  7. 如何从软硬件层面提升 Android 动画性能?

    若是有人问如何解决动画性能不佳的问题,Dan Lew Codes 总会反问:你是否使用了硬件层? 动画放映过程中每帧画面可能都要重绘.如果使用视图层,,渲染过的视图可以存入离屏缓存以待将来重用,而无需 ...

  8. 用CSS开启硬件加速来提高网站性能

    国外一篇文章,有点意思,转载过来,准备尝试下~ 中文地址:http://www.cnblogs.com/rubylouvre/p/3471490.html 原文地址:http://blog.teamt ...

  9. 用CSS开启硬件加速来提高网站性能(转)

    翻译文章,原文地址:http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-cs ...

随机推荐

  1. Java ->在mybatis和PostgreSQL Json字段作为查询条件的解决方案

    Date:2019-11-15 读前思考: 你没想到解决办法? PostgreSQL 数据库本身就支持还是另有解决办法? 说明:首先这次数据库使用到Json数据类型的原因,这次因为我们在做了一个app ...

  2. redhat 配置eth0网卡

                 redhat 找不到eth0等网卡设备 Serenity关注                                                         ...

  3. [java] 笔记 from黑马

    1. 关于String的创建.   PS:String的底层是用字节数组来实现的. 2.字符串常量池的笔记 具体指向是如下图的, 注意看0x666和0x999这两个地址. 3.原因如下: 4. 5. ...

  4. 4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)

    你好,我是彤哥,本篇是netty系列的第四篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使 ...

  5. 【Java】面向对象之继承

    多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可.其中如图中所示,食草动物.食肉动物.兔子.羊.狮子.豹都可以称为子类,动物类称为父 ...

  6. 原生js实现简单的下拉加载

    #获取当前滚动条的高度document.documentElement.scrollTop #获取当前窗口的高度 document.documentElement.clientHeight #获取当前 ...

  7. IDEA最常用快捷键汇总+快速写出Main函数

    IDEA可以说是当下Java程序员日常开发的神器,但是想要发挥这款神器的牛逼威力,必须得熟练使用它的各种快捷键才行.本篇总结下使用IDEA(也就是IntelliJ IDEA )进行日常开发中最常用的快 ...

  8. 根据json数据中某一个属性 处理数组重组的方法 (二种)

    需求:根据role 的不同分组 渲染页面 进行后期操作 后台返回数据:   因为后台返回的json数据不是我们想要的 所以就得自己来了~  要啥样整啥样 js: 第一种处理方法 使用方法: 1: th ...

  9. toString() 方法的参数

    除开null 和 undefined之外所有的数据类型都是拥有toString方法的. 通常情况下我们使用toString()方法的时候都是不用传递参数的,但是Number类型的toString方法是 ...

  10. 【NHOI2018】拆除桥墩

    [解题思路] 求最窄的地方的最大值,可以推测此题用二分答案. 那么二分答案的check函数该如何写呢? 由于通航能力是由最窄的地方决定的,那么就要保证每个桥墩之间的距离都大于或等于二分的答案,那么只要 ...