梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画
CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能。
一、两者的主要区别
先开门见山的说说两者之间的区别。
1)CSS动画:
基于CSS的动画一般由浏览器“主线程”之外的独立线程处理,在其中执行样式、布局、绘制和 JavaScript。
使用CSS动画,允许对单个动画关键帧、持续时间和迭代进行更多控制。
但缺乏表现力,并且很难有意义地组织动画,这意味着创造动画会带来较高的复杂度和错误率。
2)JavaScript动画:
在浏览器主线程的JavaScript中运行,主线程已经忙于运行其他的JavaScript,样式的计算,布局还有绘制。线程内存在资源竞争,这实质上增加了掉帧的风险。
基于JavaScript的动画灵活性更高,完全控制元素在每个步骤,能更好的实现复杂的动画和大量的交互(例如当要求所有的元素在页面加载时顺次加载显示出来)
对于多元素多步骤的动画序列、交互拖拽动画等,用JavaScript实现则是上选。
二、页面渲染
1)步骤
为了能让动画高性能的执行,得先了解一下页面渲染。
页面渲染的一般过程为JavaScript > 计算样式 > 布局 > 绘制 > 渲染层合并。

Layout:计算每个DOM元素最终在屏幕上显示的大小和位置。页面中一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。
Paint:绘制文字、颜色、边框和阴影等,也就是一个DOM元素所有的可视效果。这个绘制过程可能会在多个层上完成的。
Composite:在每个层上完成绘制之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上。
2)优化

Layout(重排)和Paint(重绘)是整个环节中最为耗时的两环,所以我们尽量避免着这两个环节。
为了实现上述效果,就需要只使用那些仅触发Composite的属性。
可以选择transform和opacity,animate.css中很多的动画都是用这两个属性实现的。
从Css Triggers的网页中可以看到两个属性的描述:

多层绘制方式的好处是,使用tranform来实现移动效果的元素将会被正常绘制,同时不会触发对其他元素的绘制。

《H5动画60fps之路》中通过一张图,总结了一些针对性的优化方法:

优化方法中提到了一个属性will-change,可以将元素提升为合成层,不过兼容性不太友好。
对于不支持此属性的,可以使用一个3D transform属性来强制浏览器创建一个新的渲染层,也就是人们常说的硬件加速。
.css{
transform: translate3d(0,0,0);
}
做过一个大转盘抽奖的项目,当使用“transform:rotate(0deg)”没有创建一个新的渲染层,那么就会在不停的重绘,高亮的地方就是重绘。

当改用“transform:rotate3d(0,0,1,0deg)”新增一个渲染层后,只会重绘一次,在电脑上看不出性能区别,在手机上就会非常明显,卡的不能动。

3)工具
在Chrome浏览器中,有工具可以查看到重绘与合成层。

Paint Flashing:就是看重绘,重绘的地方会高亮。
Layer Borders:黄褐色就是合成层,青色的细线是浏览器渲染时候的“瓦片”,浏览器绘制页面的时候只会绘制可视区域一定范围内的瓦片,以节省性能开销。

三、动画相关事件
1)CSS动画事件
CSS动画有两种方式设置Transition过渡和Animation。
与过渡相关事件只有一个TransitionEnd,也就是在过渡结束后触发。
与animation相关事件有三个,animationstart、animationiteration与animationend。
两个动作相关的事件比较少,所以控制动画非常有限制,应对复杂场景蛮吃力的。
2)requestAnimationFrame
requestAnimationFrame函数就是针对动画效果的API,与显示器固定的刷新频率保持同步,利用这个刷新频率进行页面重绘,一般来说,这个频率为每秒60帧。
此外,一旦页面不处于浏览器的当前标签,就会自动停止刷新,这就节省了CPU、GPU和电力。
这个函数是在主线程上完成,如果主线程非常繁忙,那么动画效果会降低。
我们常用的setInterval、setTimeout是开发者主动要求浏览器去绘制,因为动画不会与屏幕的刷新率同步,很可能出现抖动和跳帧。
各个浏览器对此函数的支持程度不一样,可能需要添加前缀,也可能需要Polyfill一下。
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
上面的代码按照1秒钟60次(大约每16.7毫秒一次),来模拟requestAnimationFrame。
参考资料:
HTML5探秘:用requestAnimationFrame优化Web动画
梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画的更多相关文章
- 原生Ajax 和Jq Ajax
前言:这次介绍的是利用ajax与后台进行数据交换的小例子,所以demo必须通过服务器来打开.服务器环境非常好搭建,从网上下载wamp或xampp,一步步安装就ok,然后再把写好的页面放在服务器中指定的 ...
- Go语言解密上篇中用java aes实现的加密
上一篇java aes文件加解密中加密的梅须逊雪三分白,雪却输梅一段香.使用go语言解密. 解密代码如下: AESUtil.go package util import ( "crypto/ ...
- JAVA AES文件加解密
AES加解密算法,代码如下: /** * Created by hua on 2017/6/30. */ import javax.crypto.Cipher; import javax.crypto ...
- 纯HTML5APP与原生APP的差距在哪?
笔者写过一些纯H5的APP,虽然开发起来的确很快很舒服,但和原生比起来纯H5APP还是有很多问题,主要聚集在以下几个方面: 1.动画 动画有很多种,比如侧边栏菜单的滑入滑出.元素的响应动画.页面切换之 ...
- compass做雪碧图
由于最近没什么时间好好写博文,我把用sass做雪碧图的关键点贴出来方便自己记忆: config.rb注释 # Set this to the root of your project when dep ...
- css之background-position属性实现雪碧图
什么是雪碧图 雪碧图就是CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,就是把多张小图标合并到一张图片上,然后用css的background-position来显示需要显示的部分 ...
- 雪妖现世:给SAP Fiori Launchpad增添雪花纷飞的效果
1995年7月,台湾大宇公司发布了一款国产单机角色扮演游戏神作:<仙剑奇侠传1>,所谓"一包烟,一杯茶",就能在电脑面前坐一整天. 这么经典的游戏Jerry当然已经通关 ...
- CSS-sprit 雪碧图
CSS-sprit 雪碧图 可以将 多个小图片统一保存到一个大图片中,然后通过调整background-position来显示响应的图片 这样图片会同时加载到网页中 就可以避免出现闪烁 ...
- 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...
随机推荐
- Unity3d学习 预设体(prefab)的一些理解
之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...
- Android UI体验之全屏沉浸式透明状态栏效果
前言: Android 4.4之后谷歌提供了沉浸式全屏体验, 在沉浸式全屏模式下, 状态栏. 虚拟按键动态隐藏, 应用可以使用完整的屏幕空间, 按照 Google 的说法, 给用户一种 身临其境 的体 ...
- 虾扯蛋:Android View动画 Animation不完全解析
本文结合一些周知的概念和源码片段,对View动画的工作原理进行挖掘和分析.以下不是对源码一丝不苟的分析过程,只是以搞清楚Animation的执行过程.如何被周期性调用为目标粗略分析下相关方法的执行细节 ...
- JavaScript中fn()和return fn()
看博客时,注意到return的重要性 参考:http://www.cnblogs.com/raoyunxiao/p/5644032.html 看似反常的例子: var i = 0; function ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-补充WebApi与Unity注入-配置文件
系列目录 上一篇演示了WebApi利用Unity注入 很多人问我如何用配置文件来配置注入,本节演示如何利用配置文件来注入,道理是一样的,跳转到上一节下载源码一起来动手! 1.打开源码定位到文件Depe ...
- .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?
配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置:第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置.要了解配置同步机制的实现原理,先得从认识一个 ...
- C#使用Aspose.Cells导出Excel简单实现
首先,需要添加引用Aspose.Cells.dll,官网下载地址:http://downloads.aspose.com/cells/net 将DataTable导出Xlsx格式的文件下载(网页输出) ...
- 灵魂宝石 bzoj 2663
灵魂宝石(1s 128MB)soulgem [问题描述] "作为你们本体的灵魂,为了能够更好的运用魔法,被赋予了既小巧又安全的外形" 我们知道,魔法少女的生命被存放于一个称为灵魂宝 ...
- Java程序员应该了解的10个面向对象设计原则
面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...
- HTML5 Page Visibility
什么是 Page Visibility ? Page Visibility 即页面可见性,通过 visibilityState 的值检测页面当前是否可见.当一个网站是可见或点击选中的状态时 Page ...