前端动画知多少?
卡沃尔(cover)博士
我和动画的故事
2014年第一个“动画作品”
动画定义
如何实现动画
浏览器如何渲染动画
动画性能提升
提问环节
实践题
---
序
前端如何看待动画?
动画师的眼中:
根据自己的意图让没有生命的东西动起来,从而变得有生命!— 薮下 泰司(やぶした たいじ)
科学家的眼中:
动画的基本原理是依靠人类具有视觉暂留的特性人的眼睛看到一幅画或一个物体后,在1/24秒内不会消失。利用这一原理,在一幅画还没消失前播放下一幅画,就会给人造成流畅的视觉变化效果
卡沃尔的眼中:
前端的动画是一件了不起的事情。
制作动画 = 制作生命
动画形成 = 较高的FPS
前端会动画 = 牛逼
前端如何实现动画?
GIF
CSS
transform、 transition、 animation
JS
定时器(RAF) + js样式设置
H5
canvas / svg / webgl
对比
实现方式 | 成本 | 灵活性 | 场景 |
---|---|---|---|
GIF | 十分容易 | 只有展现和消失 | 状态动画 |
CSS | 容易 | 过程不可控 | 常规变形如旋转,伸缩 |
定时器+js样式设置 | 一半 | 灵活 | 需要过程控制的动画,如loading等 |
canvas/webgl | 较高 | 灵活 | 涉及元素多,多绘制的,如游戏,或者下雪等特效 |
svg | 一般 | 一般 | 矢量,简单 |
浏览器是如何渲染的?
像素渲染流水线
Javascript
js操作,如排序,添加dom
Style 计算样式
根据CSS选择器计算dom元素的样式规则
Layout 布局
计算DOM最终在屏幕上显示的大小和位置
Paint 绘制
本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影
Composite 渲染层合并
在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上
视觉发生变化,如何渲染?
全流水
触发条件: 如修改宽高,位置
无relayout流
触发条件: 如修改背景图片,文字颜色
无relayout + repaint 流
触发条件: 使用那些仅触发渲染层合并的属性
如(transform 或 opacity)
动画如何提升性能?
Javascript
- 对于动画效果的实现,避免使用setTimeout或setInterval,请使用requestAnimationFrame。
- 把耗时长的JavaScript代码放到Web Workers中去做。
- 把DOM元素的更新划分为多个小任务,分别在多个frame中去完成。
- 使用Chrome DevTools的Timeline和JavaScript Profiler来分析JavaScript的性能。
Style
- 降低样式选择器的复杂度;使用基于class的方式
- 减少需要执行样式计算的元素的个数。
Layout
- 需要布局的DOM元素的数量直接影响到性能;应该尽可能避免触发布局。
- 分析页面布局模型的性能;新的Flexbox比旧的Flexbox和基于浮动的布局模型更高效。
- 避免强制同步布局事件的发生;对于元素的样式属性值,要先读再写。
Paint
- 通过渲染层提升和仔细规划动画渲染来减小绘制区域
- 使用Chrome DevTools的来分析绘制复杂度和时间消耗;
Composite
- 只使用transform/opacity来实现动画效果
- 用will-change/translateZ属性把动画元素提升到单独的渲染层中
- 避免滥用渲染层提升:更多的渲染层需要更多的内存和更复杂的管理
- 使用transform/opacity来实现动画效果
2. 用will-change/translateZ属性把动画元素提升到单独的渲染层中
即3D加速
硬件加速原理
创建动画元素的compositor layout
3D加速
上传纹理到GPU处理
GPU合成
GPU
translate vs translate3d
3D动画
浏览器在页面渲染前为创建独立的复合图层
3D 和 2D transform 的区别
2D动画创建
动画开始时,才创建独立的复合图层
开启3D加速就一定好?
假如你有一辆跑车,很牛逼的那种
在一条拥挤的道路上,再快的跑车效果也不大
硬件加速那么好,我就这样做?
- 为每一个元素都创建图层会非常消耗内存;
- CPU上传纹理到GPU中会有带宽的限制;
- 开启GPU加速消耗大量的电量。
按需创建。
提问环节
要问问题,请举手
小结
前端动画水很深,
因此想要牛逼 = 需要继续努力!
后话
之后有机会给大家,讲下如何用开发者工具,调试动画性能。。。。
前端动画知多少?
By coverguo
前端动画知多少?
- 789