美文网首页
web高性能动画及渲染原理

web高性能动画及渲染原理

作者: mkv_me | 来源:发表于2017-12-24 17:11 被阅读0次

如何实现动画?

  • jQuery animation:setTimeout,top/left
  • animatin,transition,transform
  • javascript+canvas/webGL/SVG
  • requestAnimationFrame
  • GPU acceleration(硬件加速)

webkit的渲染流程

webkit 分析性能

css style影响

style影响

浏览器渲染小结

  • 渲染三个阶段: Layout,Paint,Composite Layers
  • 修改不同CSS属性会触发不同阶段
  • 触发的阶段越前,渲染的代价越高

硬件加速(GPU加速)

  • Texture,即GPU传输到GPU的一个Bitmap
  • GPU能快速对texture进行偏移、缩放、旋转、修改透明度等操作
CPU vs GPU
  • 相同之处:两者都有总线和外界联系,有自己缓存体系,以及数字和逻辑运算单元。一句话,两者都为了完成计算任务而设计。
  • 不同之处:CPU主要负责操作系统和应用程序,GPU主要负责跟显示相关的数据处理,GPU的活CPU一般都可以干,但是效率低下

Layer模型

  • 浏览器根据CSS属性为元素生成Layers
  • 将Layers作为texture上传到GPU
  • 当改变Layer的transform,opacity属性时,渲染会跳过Layout,paint,直接通知GPU对Layer做变换。
Layer创建标准
  1. 拥有3d transform属性
  2. 使用animation,transition实现opacity,transform的动画
  3. video
  4. canvas
  5. Flash
  6. 使用CSS filters的元素
  7. z-index大于某个相邻节点的Layer的元素
为什么使用硬件加速快呢?
  • 如果使用jquery或者js来做一个top移动100px的动画,每次都会重主线程发传到合成器线程
  • 但是,如果用GPU transform来做的话,主线程只会传一次到合成器线程,其余任务全部是在合成器线程,所以效率比较高。
节省了哪些时间?
  • CPU进行Layout和paint的时间
  • CPU向GPU传输位图的时间
完美的Animation

对眼睛来说:60FPS更舒服更完美
约等于16.7ms内,我们准备好一帧的动画

  • 开始绘制的时间
  • 绘制一帧的时间
  1. setTimeout(callback,1/60)
    依靠浏览器内置时钟更新频率,eg、IE8及以前更新间隔为15.6,setTimeout 16.7,它需要两个15.6ms触发。超过14.5ms,所以会出现丢帧的现象
    main thread队列
  2. requestAnimationFrame
    • 定义绘制每一帧的工作requestAnimationFrame(callback)
  • 自动调节频率 ,callback工作太多无法再一帧内完成,会自动降低为30fps,虽然频率降低但比丢帧好。

Layout

触发Layout
  • 改变widht,height等和大小、位置相关的属性
  • 读取size、positoin相关的属性


    会引起layout

尽量不触发Layout,使用transform代替top,left的动画。

会触发三次layout
只触发一次layout

但是,如果是这样


1

我们可以这样改


2
介绍一个库

fastdom.js
在每一帧,先将读操作批量运行,在批量运行写操作

Layout小结

  • 不但改变css可能导致Layout,读取位置大小相关属性也会导致Layout(滚动条也会导致Layout)
  • 分离读写,减少Layout
  • 面对解耦代码,可以使用rAF推迟的方法分离读写

如何开发不会导致重拍

  1. 样式表越简单,重拍和重汇越快
  2. 重拍和重绘的DOM元素层级越高,成本就越高
  3. table元素的重排和重绘成本,要高于div元素
  4. 尽量不要把读操作和写操作,放在一个语句里
  5. 统一改变样式
  6. 缓存重排结果
  7. 离线DOM Fragment/clone
  8. 虚拟DOM React
  9. 必要的时候display:none不可见元素不影响重排重绘。visibility对重排影响不影响重绘

Paint

触发paint
  • 当修改border-radius,box-shadow,color等展示相关属性,会触发paint
paint的代价
  • continuous painting mode
  • paint prefiler
  • 在经常paint的区域,要避免代价太高的style(比如不要的gif图设置display:none)
减少不必的绘制
  • gif图即使被其他Layout盖住不可见,也可能导致paint,不需要时应将gif图的display属性设为none。轮播图也一样 http://jsbin.com/dizak/3/edit?html,css,output (可以用调试工具去测试性能,z-index:0,也会重排重绘,应该直接设置display:none)
  • 减少绘制区域,为引起大范围Paint的元素生成独立的Layout以减小Paint的范围
Paint小结
  • 简化绘制的复杂度
  • 避免不必要的绘制
  • 减少绘制区域

composite Layout

  • GPU也是有限度的,不要滥用GPU资源生成不必要的Layout
  • 留意以外生成的Layout

国外一个关于高性能动画研究

相关文章

网友评论

      本文标题:web高性能动画及渲染原理

      本文链接:https://www.haomeiwen.com/subject/dudhgxtx.html