GPU加速是什么

Wesley13
• 阅读 472

GPU加速是什么

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

一. GPU 加速能做什么?

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

  • 大多数设备的刷新频率是 60 次/秒,(1000/60 = 16.6ms)也就说是浏览器对每一帧画面的渲染工作要在 16ms 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。

  • 浏览器在一帧里面,会依次执行以下这些动作。减少或者避免 layout,paint 可以让页面不卡顿,动画效果更加流畅。

GPU加速是什么

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

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

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

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

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

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

GPU加速是什么

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

@keyframes demo {  0% {      top: 10px;  }  100% {      top: 30px;  }}

优化

@keyframes demo {  0% {      transform: translateY(10px);  }  100% {      transform: translateY(30px);  }}

二. GPU 是什么,如何用 Chrome devtools 进行分析 debug?
浏览器渲染一个页面大致是按照下面这个步骤执行。
  1. 获取 DOM 并将其分割为多个层(RenderLayer)

  2. 将每个层栅格化,并独立的绘制进位图中

  3. *将这些位图作为纹理上传至 GPU *

  4. 复合多个层来生成最终的屏幕图像(终极 layer )。

Chrome 开启查看 renderlayer

GPU加速是什么

按上面的步骤之后,即可看到
GPU加速是什么

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

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

Chrome 查看 layer
  • 打开 timeline 进行录制,选中 timeline 的某一帧,然后选择下面的 layer ,可以左右拖动该模块出现 3d。
    我们可以看到一个页面实际是像下面一样组成的
    GPU加速是什么

  • 从上图不难理解,虽然我们最终在浏览器上看到的只是一个复印版,即最终只有一个层。类似于PhotoShop软件中的“图层”概念,最后合并所有可视图层,输出一张图片到屏幕上。但实际上一些dom会因为一些规则被提升成独立的层(开启 GPU 加速),一旦被独立出来之后,便不会再影响其他dom的布局,因为它改变之后,只是“贴上”了页面。

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

GPU加速是什么


三. 如何开启 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会提升为合成层

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


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

拿实际项目举个栗子,我们按照上面的步骤开启 layer borders
GPU加速是什么

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

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

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

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

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

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

GPU加速是什么

总结

整篇文章介绍了下面几个部分
  • GPU 加速能做什么

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

  • 如何开启 GPU 加速?

  • GPU 加速隐藏的坑--隐式合成

参考:

本文分享自微信公众号 - 凹凸实验室(AOTULabs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这