GPU 加速到底是个啥?

众所周知,网页不仅应该被快速加载,同时还应该流畅运行,比如快速响应的交互,如丝般顺滑的动画……

一. GPU 加速能做什么?

首先我们要了解什么是 16ms 优化

  • 大多数设备的刷新频率是 60 次/秒,(1000/60 = 16.6ms)也就说是浏览器对每一帧画面的渲染工作要在 16ms 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。
  • 浏览器在一帧里面,会依次执行以下这些动作。减少或者避免 layout,paint 可以让页面不卡顿,动画效果更加流畅。

1. JavaScript:JavaScript 实现动画效果,DOM 元素操作等。

2. Style(计算样式):确定每个 DOM 元素应该应用什么 CSS 规则。

3. Layout(布局):计算每个 DOM 元素在最终屏幕上显示的大小和位置。由于 web 页面的元素布局是相对的,所以其中任意一个元素的位置发生变化,都会联动的引起其他元素发生变化,这个过程叫 reflow。

4. Paint(绘制):在多个层上绘制 DOM 元素的的文字、颜色、图像、边框和阴影等。

5. Composite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。

利用 GPU 加速优先使用渲染层合并属性,避免 layout,paint。

从上图可以看出,可以通过改变元素的 transform 实现移动,伸缩变换而非改变物体的 left,top,width,height 避免 layout,paint。让动画效果更加流畅。

优化

二. GPU 是什么,如何用 Chrome devtools 进行分析 debug?

浏览器渲染一个页面大致是按照下面这个步骤执行。

1. 获取 DOM 并将其分割为多个层(RenderLayer) 2. 将每个层栅格化,并独立的绘制进位图中 3. 将这些位图作为纹理上传至 GPU 4. 复合多个层来生成最终的屏幕图像(终极 layer )。

Chrome 开启查看 renderlayer

按上面的步骤之后,即可看到

1. 黄色边框:有动画 3d 变换的元素,表示放到了一个新的复合层(composited layer)中渲染

2. 蓝色的栅格:这些分块可以看作是比层更低一级的单位,这些区域就是 RenderLayer 打开一个页面,如果该页面的黄色边框很多,那么肯定要查看一下原因了

Chrome 查看 layer

  • 打开 timeline 进行录制,选中 timeline 的某一帧,然后选择下面的 layer ,可以左右拖动该模块出现 3d。 我们可以看到一个页面实际是像下面一样组成的
  • 从上图不难理解,虽然我们最终在浏览器上看到的只是一个复印版,即最终只有一个层。类似于PhotoShop软件中的“图层”概念,最后合并所有可视图层,输出一张图片到屏幕上。但实际上一些dom会因为一些规则被提升成独立的层(开启 GPU 加速),一旦被独立出来之后,便不会再影响其他dom的布局,因为它改变之后,只是“贴上”了页面。

根据这个优点,我们可以把页面中一些布局经常变换的dom(动画)提升到独立的层。那么,浏览器在之后的 16ms 中,只需进行下面的几个步骤。

三. 如何开启 GPU 加速?

目前下面这些因素都会引起Chrome创建合成层:

1. 3D 或透视变换(perspective,transform) CSS 属性 2. 使用加速视频解码的video元素 3. 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 canvas 元素 4. 混合插件(如 Flash) 5. 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素 6. 拥有加速 CSS 过滤器的元素 7. 元素A有一个 z-index 比自己小的元素B,且元素B是一个合成层(换句话说就是该元素在复合层上面渲染),则元素A会提升为合成层。

上面7点都非常容易理解,在日常开发中,最容易出现问题的是第7点

四. GPU 加速隐藏的坑–隐式合成

  • 元素A有一个 z-index 比自己小的元素B,且元素B是一个合成层(换句话说就是该元素在复合层上面渲染)

拿实际项目举个栗子,我们按照上面的步骤开启 layer borders

尚未给上图右手添加高层级的 z-index 时,整个页面在移动端打开后闪退。而添加了 z-index 之后,页面正常显示,不闪退了。 仔细看上面的 gif ,仅仅改变了 z-index ,就会改变大批数量的层(黄色边框)

为什么 z-index 力量这么大?

我们来看一个栗子,B 在做动画,理所当然把B提到单独的合成层。减少重绘。

按照上图,我们遇到一个逻辑问题,元素B应该在单独的合成层上,并且屏幕的最终图像应该在 GPU 上组成。但是A元素在B元素的顶部,我们没有指定提升A元素自身层级的东西。那么浏览器会做什么?它将强制为元素A创建一个新的合成图层。 这样,A和B都被提升到单独的复合层。 因此,使用 GPU 加速提升动画性能时,最好给当前动画元素增加一个高一点的 z-index 属性,人为干扰复合层的排序,可以有效减少 Chrome 创建不必要的复合层,提升渲染性能。

注意:GPU 不仅需要发送渲染层图像到 GPU ,而且还需存储它们,以便稍后在动画中重用。别盲目创建渲染层,一定要分析其实际性能表现。因为创建渲染层是有代价的,每创建一个新的渲染层,就意味着新的内存分配和更复杂的层的管理。对于使用移动设备的用户来说是很坑的。移动设备没有台式机那么多的内存。过多的 GPU 加速会引起页面卡顿甚至闪退。

找到 layers,点击当前层,在右边查看占用的 memory(内存)

总结

整篇文章介绍了下面几个部分

● GPU 加速能做什么 ● GPU 是什么,如何用 Chrome devtools 进行分析 debug? ● 如何开启 GPU 加速? ● GPU 加速隐藏的坑–隐式合成

参考:

http://www.jianshu.com/p/a32b890c29b1

http://div.io/topic/1348

原文发布于微信公众号 - AI研习社(okweiwu)

原文发表时间:2017-04-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我分享我快乐

响应式jquery小效果实现思路

有很多同学在实现jquery效果时,不知道怎样符合响应式布局。我写了个小案例,帮大家找找思路,希望能帮到你。 效果如下: ? 代码如下: <!doct...

38911
来自专栏生信宝典

WB图片处理-教你利用PPT做出漂亮的WB图片!

WB是很科研多小伙伴都会用到的实验技术,而对于最终WB图片的处理也是各自有各自的手段,不过主流主要分为两大派:PPT或者Adobe Photoshop/Illu...

1.9K2
来自专栏非著名程序员

目标:双向拖动的自定义View

国际惯例先预览后实现 ? 我们要实现的就是一个段位样式的拖动条,用来做筛选条件用的, 细心的朋友可能会发现微信设置里面有个一个通用字体的设置, 拖动然后改变字...

2326
来自专栏美团技术团队

关于刘海打理这种事儿,美团点评的iOS工程师早就有经验了,不信你看!

背景 iPhone X 刘海机于9月13日发布,给科技小春晚带来一波高潮。作为开发人员却多出来一份忧虑,iPhone X 怎么适配?我们 App 的脑袋会不会也...

3697
来自专栏小灰灰

Css实战训练之图片点击放大

Css实战训练之图片点击放大 I. 背景 非常常见的一个功能了,一般网站上显示的都是缩略图,等你点击缩略图之后,会在一个弹框中显示放大的图片 那么这个功能是怎么...

9464
来自专栏数据小魔方

条件格式单元格图表

今天跟大家分享条件格式单元格图表! ▼ 这类图表比较特殊,不是通过excel的内置图标库制作,而是通过excel的条件格式工具制作的存放在单元格中的图表。这种图...

4128
来自专栏非著名程序员

一个类似于进度和打卡进度的自定义view

一个类似于进度和打卡进度的自定义view ---- 如下图: ? 看GIF岂不是更好 ? ---- 这个view在现在的app中挺常见的,基本都是这个套路, -...

2108
来自专栏生信宝典

一分钟绘制磷脂双分子层:AI零基础入门和基本图形绘制

Adobe illustrator是一种应用于出版、多媒体和在线图像的工业标准矢量插画的软件,是一款非常好的图片处理工具,简称AI。

1.5K3
来自专栏hbbliyong

Extjs 项目中常用的小技巧,也许你用得着(2)

接着来,也是刚刚遇到的 panel怎么进行收缩 这会panel就会出现这个 ? 点这个就可以收缩了 collapsible: true, pa...

3376
来自专栏Guangdong Qi

iOS开发常用之图像浏览及处理

2615

扫码关注云+社区

领取腾讯云代金券