如何书写高性能的动画

通过渲染原理来看动画

单页面渲染

单页面渲染过程

  1. HTML和Css 经过解析会分别生成cssomDom
  2. 两个进行结合生成渲染树

渲染树

  1. layout是确认元素大小和相互关系的过程

layout操作

  1. point 渲染成位图.
  2. composite 位图由cpuGPU 再到 屏幕, 完成一次渲染过程

浏览器也会记录记录下来每次渲染过程.

浏览器记录

打开控制台到Performance选项卡, 点击record开始记录, 记录完成再点stop

示意图

高性能动画

因为layout, pointcomposite 远比前面的过程耗时,所以我们就关注在这三个过程.

不同的属性重新渲染的过程都是不一样的.详情可(Css Triggers)[csstriggers.com/] 比如Top属性在任何内核都需要经历三个阶段, 而align-cententGecko内核下重新渲染只需要composite一个步骤.

硬件加速

硬件加速也叫作GPU加速,GPU渲染只触发Composite过程,速度极快, 而它擅长对texture(纹理)进行偏移, 放大, 旋转等操作.
可以通过layer模型来触发硬件加速.

layer的触发条件

  1. 属性 3D perspectivetransform;
  2. 使用 animation, transition 改变opacitytransfrom元素;
  3. video canvas flash css filters 标签.

以后我们做项目可以尽量考虑以上三种, 可以极大提高动画性能.

requestAnimationFrame

动画的刷新频率 = 1/60FPS, 要动画流畅我们必须在约16.7ms内将一帧内容准备完成. 换个角度, 如果屏幕每秒渲染60帧画面, 但是为了流畅动画必须提供60帧的画面, 不然就会出现卡顿. 但是如果一次刷新间隔中提供多帧,
那么最后的帧就会覆盖前面的帧, 就会造成失帧, 所以我们在一次刷新间隔只包含一帧动画,才能确保流畅.
动画流畅
但是我们不清楚刷新频率,每个设备每次刷新时长都不固定, 那如何实现只包含一帧的操作呢.我们需要requestAnimationFrame来实现.

requestAnimationFrame会自动调节执行频率.确保刷新间隔只包含一帧.

调用形式为requestAnimationFrame(callFun)
Calfun中将一帧DOM内容完成, 值得注意的是requestAnimationFrame隐藏和不可见元素无效, 页面未激活时requestAnimationFrame无效的

小方块从最右开始运动到触碰最左端停止 Demo

目标 16.7ms

目标: 每一帧的渲染时间小于16.7ms

  1. 尽量触发layer
  2. 不能改变 width height margin等和大小位置相关的属性, 尽量使用transform代替top, left
  3. 为了确保结构正确, 修改下列属性时会触发layout操作,一次性操作,先读后写.
clientHeight, clientLeft, clientTop, clientwidth, focus(),
getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrol1ByL ines(),
scrollByPages(), scrol1Height, scrol1IntoView(),scrol1IntoViewIfNeeded(),scrollLeft, scrollTop, scrol1Width 
复制代码

还原动画

动画是由不同时刻的位图渲染而成, 所以只需要将关键帧的状态描述清楚就可以还原出合格的动画.状态是由最初的状态对比而成.

Todo

  • [] 还原动画的demoa
  • [] 了解重绘和回流
  • [] 测试Demo
  • [] 熟悉performance动画记录
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享