3D硬件加速提升动画性能 与 z-index属性
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』选项,如果页面有很多黄色的框肯定是不对的。
3D硬件加速提升动画性能 与 z-index属性的更多相关文章
- 使用CSS3开启GPU硬件加速提升网站动画渲染性能
遇到的问题: 网站本身设计初衷就没有打算支持IE8及以下版本浏览器,并不是因为代码兼容性问题,而是真的不想迁就那些懒得更新自己操作系统和浏览器的用户,毕竟是我自己的网站,所以我说了算!哈哈~ 没有了低 ...
- CSS开启硬件加速提高网站性能
国外一篇文章,有点意思,转载过来,准备尝试下~ 中文地址:http://www.cnblogs.com/yzw7489757/ 原文地址:http://blog.teamtreehouse.com/i ...
- 使用css来开启硬件加速来提高网站性能
一.什么是硬件加速 硬件加速就是将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器,这样就可以使得animation与transition更加顺畅.我们可以在浏览器中用css开启硬件加速 ...
- GPU硬件加速原理 /转
现代浏览器大都可以利用GPU来加速页面渲染.每个人都痴迷于60桢每秒的顺滑动画.在GPU的众多特性之中,它可以存储一定数量的纹理(一个矩形的像素点集合)并且高效地操作这些纹理(比如进行特定的移动.缩放 ...
- GPU硬件加速
现代浏览器大都可以利用GPU来加速页面渲染.每个人都痴迷于60桢每秒的顺滑动画.在GPU的众多特性之中,它可以存储一定数量的纹理(一个矩形的像素点集合)并且高效地操作这些纹理(比如进行特定的移动.缩放 ...
- 盒子端 CSS 动画性能提升研究
不同于传统的 PC Web 或者是移动 WEB,在腾讯视频客厅盒子端,接大屏显示器(电视)下,许多能流畅运行于 PC 端.移动端的 Web 动画,受限于硬件水平,在盒子端的表现的往往不尽如人意. 基于 ...
- 如何从软硬件层面提升 Android 动画性能?
若是有人问如何解决动画性能不佳的问题,Dan Lew Codes 总会反问:你是否使用了硬件层? 动画放映过程中每帧画面可能都要重绘.如果使用视图层,,渲染过的视图可以存入离屏缓存以待将来重用,而无需 ...
- 用CSS开启硬件加速来提高网站性能
国外一篇文章,有点意思,转载过来,准备尝试下~ 中文地址:http://www.cnblogs.com/rubylouvre/p/3471490.html 原文地址:http://blog.teamt ...
- 用CSS开启硬件加速来提高网站性能(转)
翻译文章,原文地址:http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-cs ...
随机推荐
- webpack的npm扩展使用
一.NPM的扩展使用 (1) npm init:初始化一个Node.js项目------创建必须的package.json文件 npm init -y:创建必须的package.json文件 (2) ...
- RTX消息提醒工具设计文档
为什么要做 项目上线后,系统依然由各业务模块负责人自己维护.而后台运行的各种业务服务结果,不能及时反馈到业务负责人.而等到客户反馈时则会太被动.为了能及时发现并解决项目问题,设计了该工具. 可利用资源 ...
- Ubuntu清空回收站
ubuntu 回收站的具体位置:$HOME/.local/share/Trash/ 执行如下命令清空回收站: sudo rm -fr $HOME/.local/share/Trash/files/ 如 ...
- 利用Xshell配置ssh免密码登录虚拟机,进行虚拟机与物理机的传输
先说一下 Xshell如何无密连接虚拟机: ssh登录提供两种认证方式:口令(密码)认证方式和密钥认证方式.其中口令(密码)认证方式是我们最常用的一种,这里介绍密钥认证方式登录到linux的方法.使用 ...
- VS Code 中使用 GitHub pull request 插件提交代码
VS Code作为一个代码编辑器,受到很多人的喜爱:其中有很多非常有用的插件/扩展功能,也会极大的提高我们的工作效率. 这里介绍一下GitHub pull request,用来向GitHub提交在VS ...
- 详解在Linux系统中安装JDK
本文以在CentOS 7.6中安装JDK8为例进行安装,其他系统和版本都是大同小异的. 下载 进入Oracle官方网站的下载页面. 首先,接受许可协议,如下图: 然后,根据Linux系统的位数选择要下 ...
- vue 父子组件传值,兄弟组件传值
父子组件中的传值 父向子 v-bind props <!-- 组件使用v-bind传值 --> <router :msg="msg"></rou ...
- vue学习笔记(七)组件
前言 在前面vue的一些博客中,我们几乎将vue的基础差不多学习完了,而从本篇博客开始将会进入到vue的另一个阶段性学习,本篇博客的内容在以后的vue项目中占很大的比重,所以小伙伴们需要认真学习,本篇 ...
- SpringCloud Alibaba微服务实战三 - 服务调用
导读:通过前面两篇文章我们准备好了微服务的基础环境并让accout-service 和 product-service对外提供了增删改查的能力,本篇我们的内容是让order-service作为消费者远 ...
- 微服务与Spring Cloud概述
微服务与Spring Cloud随着互联网的快速发展, 云计算近十年也得到蓬勃发展, 企业的IT环境和IT架构也逐渐在发生变革,从过去的单体应用架构发展为至今广泛流行的微服务架构. 微服务是一种架构风 ...