导语: 几个星期前,因为公司活动,需要做一个比较炫酷的H5动画, 一顿猛如虎的coding之后,发现运行起来卡成狗,当时绝望的想要出家,还好组内有经验比较丰富的动画大神帮忙调整,顺利度过难关。

作为一个有追求的程序员!!!痛定思痛!!!同样的悲剧绝对不能在同一个技术面发生两次!!!流着泪写下该篇总结,希望可以给大家一些启发。

本文目录:

  • 为什么动画会有卡顿感?

  • 浏览器渲染绘制过程

  • 强大的chrome性能分析工具介绍

  • 动画性能分析实战

  • 总结

为什么动画会有卡顿感?

回答这个问题前,我们应该要明白一个问题,为什么我们会感到动画在动?

  1. 动画的实现原理,是利用了人眼的“视觉暂留”现象,在短时间内连续播放数幅静止的画面,使肉眼因视觉残象产生错觉,而误以为画面在“动”。
  1. 大多数设备的刷新频率是 60 次/秒,(1000/60 = 16.6ms)也就说是浏览器对每一帧画面的渲染工作要在 16ms 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。

综上,我们或觉得动画卡,一个很大的原因就是因为 FPS(帧率) 过低导致,也就是说每一帧的画面不能的保证在16ms之内完成渲染工作,所以我们会觉得卡顿。

解释清楚了会感到卡顿的原因,大家是不是很好奇每一帧的渲染过程到底发生了什么会导致它的渲染时间超过 16ms ?

现在进入到我们的第二部分,浏览器渲染绘制过程

浏览器渲染绘制过程

Webkit的渲染流程为例分析下浏览器:

简单概括为如下几步:

  • 处理HTML标记数据并生成DOM树。

  • 处理CSS标记数据并生成CSSOM树。

  • 将DOM树与CSSOM树合并在一起生成渲染树。

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

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

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

每一帧的渲染经过如上步骤,呈现在用户的眼前,当这些步骤时间的总和 > 16ms, 用户就会有卡顿感产生。

在 动画性能分析 部分,会重点结合Layout, Paint, composite 部分来具体分析动画卡顿的原因及优化方式,在此之前,我们先了解下强大的 chrome 提供的性能分析工具,以便我们更好分析问题。

强大的chrome性能分析工具介绍

  • performance

使用 Performance 工具时,为了规避其它 Chrome 插件对页面的性能影响,我们最好在无痕模式下打开页面

点击左上角实心圆开始录制,看下性能分析面板。

重点介绍下图中标红处:

FPS:这是一个和动画性能密切相关的指标,它表示每一秒的帧数。图中绿色柱状越高表示帧率越高,体验就越流畅。若出现红色块,则代表长时间帧,很可能会出现卡顿。图中以绿色为主,偶尔出现红块,说明网页性能并不糟糕,但仍有可优化的空间。

CPU:表示CPU的使用情况,不同的颜色片段代表着消耗CPU资源的不同事件类型。这部分的图像和下文详情面板中的Summary内容有对应关系,我们可以结合这两者挖掘性能瓶颈。

summary: 渲染过程中,每个部分的耗时占比。

  • Layers

是不是已经被这个高逼格的界面深深震撼到了!!!

重点看下 Paint flashing, Layer borders, FPS meter:

  • Paint flashing: 标记当前正在重绘的元素,(元素会被一个绿色的半透明遮罩蒙上),如上图;

  • Layer borders: 复合层

    1. 黄色边框: 有动画 3d 变换的元素,表示放到了一个新的复合层(composited layer)中渲染。
    2. 蓝色的栅格:这些分块可以看作是比层更低一级的单位,这些区域就是 RenderLayer。
  • FPS meter: GPU性能监控

    1. Frame Rate: 帧率。
    2. GPU Raster:GPU 光栅(默认开启)。
    3. GPU Memory: GPU 使用率。

综上就是对 chrome 一些性能分析工具的简单介绍,说了这么多!!!让我们写一些动画实操一下吧!!!

下面就进入我们最最重要的部分!!!动画性能分析实战

动画性能分析实战

在浏览器中打开如下代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.react {position: absolute;width: 100px;height: 100px;background: #f00;animation: react-run 3s linear 0s infinite;}@keyframes react-run {0% { top: 0px;left: 0px;}25% {top: 0px;left: 200px;}50% {top: 200px;left: 200px;}75% {top: 200px;left: 0px;}100% {top: 0px;left: 0px;}}</style>
</head>
<body><div class="react"></div>
</body>
</html>
复制代码

运行结果:

  • Layers

  • performance

性能分析:

  1. 图中移动的小方块在不停的重排重绘过程中。

  2. GPU 的内存使用率为2.4 ~ 4.9 之间。

  3. 一秒内重排和重绘的耗时分别为7.3ms4.9ms

这里还有个值得注意的点:

  • 每次元素移动到光栅处,内存都会变大一倍从2.4变为4.9

如下图:

图层被光栅化后,分块存入GPU的内存中,当元素跨光栅移动时,两块内存都在变化,所以消耗自然加倍啦!!!

好,现在让我们开启传说中的 3D引擎加速!!!

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.react {position: absolute;width: 100px;height: 100px;background: #f00;animation: react-run 3s linear 0s infinite;transform: translate3d(0, 0, 0);}@keyframes react-run {0% {transform: translate3d(0, 0, 0);}25% {transform: translate3d(200, 0, 0);}50% {transform: translate3d(200, 200, 0);}75% {transform: translate3d(0, 200, 0);}100% {transform: translate3d(0, 0, 0);}}</style>
</head><body><div class="react"></div>
</body></html>
复制代码

运行结果:

  • Layers

  • performance

性能分析:

  1. 图中移动的小方块没有发生重排和重绘,只有一个图层合并。

  2. GPU 的内存使用率几乎为0。

  3. 一秒内重排和重绘的耗时分别为0ms0ms,图层合并时间为89us

比较上述两种写法可以得处: 开启GPU加速时的动画性能要比不开启高效。

  • 未开启GPU加速:
  • 开启GPU加速:

写到这里,大家可能会有疑问,为什么开启GPU加速就没有发生重排和重绘 ?是不是所有动画全部都开启GPU加速,就会变的很快?

下面就来分析这两个问题:

1. 为什么开启GPU加速就没有发生重排和重绘 ?

观察上图:

在开启GPU加速时,运动的红色方块开启了新的合成层,所以不用再重排重绘,只需要一个合成图层的时间。

2. 是不是所有动画全部都开启GPU加速,就会变的很快?

因为开启GPU加速后会建立新的图层,新的图层就需要一定的内存空间,而且图层在合成时,图层越多耗费的时间肯定也是越多的,所以疯狂的开启GPU加速,不但不能解决性能问题,反而可能会带来性能问题。

如下 (GPU内存使用较高):

综上所述: 合理的开启GPU加速,建立新的合成层,可以给性能带来很大的提升。

那么,都有那些放法建立新的合成层呢?

亲测有效的方法:

  • 使用css属性:

    1. transform: translate3d(0, 0, 0);
    2. will-change: '将会发生变化的属性';
    复制代码
  • 标签:

    <video></video>
    <canvas></canvas>
    复制代码

总结

通过此篇文章,我们应该对动画性能分析有一个比较系统的认识:

  1. 为什么会有卡顿感产生?
  2. 浏览器每一帧的渲染工作是怎么进行的?
  3. 如何使用chrome开发工具对动画性能进行分析?
  4. GPU加速和普通渲染的区别在哪里?
  5. 我们应该如何开启GPU加速?

动画卡顿问题的分析,不像是查找js上的bug,有逻辑可寻,所以在遇到问题时,我们只有明白底层的原理,结合分析工具,才能更好的发现问题。

兄dei,听说你动画很卡?相关推荐

  1. 大兄dei,早点看清this吧

    说道this,可以说是前端中很重要的问题之一了,也是面试或者笔试常考的问题.所以还是早点看清this吧,大兄dei. this是什么?为什么要存在? this关键字是js中最最复杂的机制之一.他被自动 ...

  2. 计算机开机出现代码卡顿,电脑开机后很卡怎么办

    电脑开机后很卡怎么办 我们都知道新电脑用起来的速度很快,那种畅快的感觉让人很舒服.但是使用时间一长,电脑就渐渐不行了,开机时间也由秒到分. 卡的原因 1.木马病毒破坏系统文件并占用大量系统资源. 2. ...

  3. 计算机运行很卡很慢,PS打开很卡怎么办?电脑太老PS运行慢如何优化?

    电脑太老PS打开很卡怎么办?虽然计算机的更新换代速度日新月异,但很多用户家里使用的都是2000以后购买的计算机,那时候的科技没有那么强大,计算机配置普遍较差,且年代久远,硬件老化,导致这些电脑连运行一 ...

  4. 自己实现call|bind|apply三兄dei

    要简单实现call.bind.apply首先要弄清楚这哥仨是啥,调用入参返回值都是什么,然后照葫芦画瓢,一点点填起来就好了: 能看思考咋实现的想必已经不需要在多赘言三个方法了,直接开始搞起: 首先这哥 ...

  5. [解锁新姿势] 兄dei 我感觉你在写bug

    前言: 继上篇 [解锁新姿势] 兄dei,你代码需要优化了 介绍一些代码的优化的小技巧. 但是我们除了在代码编写上需要优雅, 还需要编写对应的测试用例, 以此来保证代码的质量. 在这篇我们继续在学习如 ...

  6. php解决m3u8卡顿,m3u8直播源为什么移动很流畅,电信很卡

    本帖最后由 Nothend 于 2019-12-30 09:18 编辑 各位论坛大神你们好: 小弟刚给N1盒子刷了CoreELEC系统,想替换掉广电的盒子,设置好KODI后,网上找了一些直播源,在移动 ...

  7. 笔记本一打开计算机就卡,电脑一打开ps就很卡怎么回事

    有网友反映电脑打开ps很卡,打开网页或者玩游戏都没事的,怎么回事呢?首先有可能是电脑配置问题,有条件的就更换配置吧,其次还有可能是某些功能没有关闭导致电脑卡,具体情况怎么解决? 电脑太老PS打开很卡怎 ...

  8. win7为什么打开桌面上的计算机很卡很慢,windows7很卡怎么处理_windows7系统卡慢的解决方法...

    近日有用户咨询win7电脑很卡的情况,相信这种状况大家应该都有遇到过吧,我们在运行大量的软件后,电脑就会变得很卡,这个时候我们会选择关闭一些不不用的软件,但是关闭之后电脑还是很卡,使得用户非常的烦躁. ...

  9. 重装失败、PE不能使用、重装很卡 个人电脑故障处理记录

    一.重装前登陆失败:错误信息----widows root\system32\ntoskrnl.exe损坏或丢失 重装中:使用原版系统牒或GHOST系统牒重装失败 之后使用PE查看硬盘,出现错误信息: ...

最新文章

  1. 【ACM】杭电OJ 1005
  2. 方向对了?MIT新研究:GPT-3和人类大脑处理语言的方式惊人相似
  3. 2017-2018-1 20155328 《信息安全系统设计基础》第十四周学习总结
  4. mingw msys 编译 libzip
  5. 虚拟机中Ubuntu不能联网----
  6. 搭建分布式环境:Dubbo+Zookeeper
  7. 8.对Hello World程序的深入
  8. JAVA中的线程安全与非线程安全,java面试题,java高级笔试题
  9. 哈工大-基于内核栈切换的进程切换
  10. splay详解(二)
  11. 关闭SqlConnection的方法
  12. cocos creator入门教程(十八)—— creator_Director对象与资源加载策略
  13. windows11 截屏键无法使用 Print screen
  14. 【倾心整理】高级工程师手写总结,入门到顶级程序员的学习方法
  15. JAVA系统之间通信方式总结
  16. 更新品牌与Z世代交互方式|朋氪元宇宙即将内测
  17. SpringBoot+vue邮箱登录(附带多种效验)
  18. 马士兵java ppt_[马士兵JAVA教程课件.ppt
  19. 食物相克小知识http://www.best4c.com/loginForLink.do?domain=www.csdn.net
  20. 锁相环原理(PLL)

热门文章

  1. 某强人整理央视《家有妙招》不看别后悔
  2. 使用Chrome浏览器解密Base64
  3. 9.二重循环:什么是二重循环???
  4. Fusion360学习记录:螺丝螺帽
  5. 操作系统指纹探测实验
  6. C++小游戏笔记——射击小行星(附源码)
  7. VR购物Buy+是否会让线下实体店渐渐消亡?
  8. office回退版本,从2021到2019
  9. win10 uwp 如何使用DataTemplate
  10. 祛除装修异味的方法 总有一种适合你!