大概半年前,无意中在网上看到一个新的js函数requestAnimationFrame,据说,此函数可以优化传统的js动画效果,似乎是未来js动画的新方向。

当时我所在的项目正好用到了和js动画有关的技术,于是在网上查阅了一些相关资料。虽然国内外都有人写过一些关于这个js函数的文章,但大多都只是简要说明工作原理,使用方式等等,一直都没有找到验证其优势所在的示例。

今天我就自己写两个testcase验证requestAnimationFrame的优势所在。

关于requestAnimationFrame这个函数在MDN上的说明是“告诉浏览器,你想要执行一个动画,该请求要求浏览器提前安排一下下一帧动画显示时需要进行的浏览器窗口的重绘”。也就是说,调用这个api就表示告诉浏览器,下次重绘页面时,记得执行我刚刚传给你的那个逻辑。

这样做一个最大的好处就是可以避免不必要的过度重绘,关于过度重绘的产生原因MSDN上已经说得很清楚了。

于是,我的测试思路是,用js构造若干个独立的动画,每个动画都有一个定时器去控制动画的执行,动画的效果就是通过修改一个div的位置坐标,使该div围绕一点做圆周运动。

定时器用两种不同的方式实现,一种用传统的setTimeout函数,每个20ms触发一次重绘逻辑。另一种用requestAnimationFrame触发重绘逻辑。(代码见文末)

下面两幅图为同时运行1500个动画,分别使用requestAnimationFrame和setTimeout时的效果:

使用 setTimeout

使用 requestAnimationFrame

下表为在不同的动画数目情况下,使用requestAnimationFrame和setTimeout时浏览器的渲染帧数对比,单位:FPS

Animation count

500

600

700

800

900

1000

1100

1200

1300

1400

1500

reqestanimationframe

30

30

28

26

20

20

20

20

19

17

15

setTimeout

34

32

29.5

27

25.5

21.8

19.7

16

14.7

13.1

12

由上表可以看出,当animation count大于1100的时候,使用requestAnimationFrame的性能是要优于使用setTimeout的,可是当animation count小于1000的时候,使用requestAnimationFrame的性能反而要差于用传统的setTimeout

同时,在上面的测试案例中,无论动画数目是多少,我们使用setTimeout时的延迟间隔始终都是20ms,但在一些情况下适当增加这个时间间隔,setTimeout函数还能得到更好的效果。比如当animation count为1100时,如果把这个间隔调整到40ms,浏览器的帧率可以达到25.5 FPS,明显优于使用requestAnimationFrame时的20 FPS。

看到这里估计大家和我一样都很失望吧,这个传说中实现了各种优化的新api怎么表现如此差强人意呢?

结合上次我写的关于统一帧管理的blog《使用统一帧管理优化前端性能》,我又想到另一种测试场景。

仍然是用js构造若干个独立的动画,但所有这些动画都共用同一个定时器去定时更新自己的状态并重绘,详见代码中的“test case 02”部分。

还是贴两幅同时运行1500个动画,分别使用requestAnimationFrame和setTimeout时的效果:

使用 setTimeout

使用 RequestAnimationFrame

同时附上不同的动画数目情况下,使用requestAnimationFrame和setTimeout时浏览器的渲染帧数对比,单位:FPS

Animation count

500

600

700

800

900

1000

1100

1200

1300

1400

1500

reqestanimationframe

30

30

30

30

29.5

28

20

20

20

20

20

setTimeout

37.5

35

34.4

32

31.5

29.5

29

26.5

25

24.3

23

由上表可见,当使用一个定时器控制所有动画的时候,使用setTimeout函数在各种动画数目场景下,其效果均优于使用requestAnimationFrame函数。

通过上面的两个测试案例,我们可以看到requestAnimationFrame函数似乎并不像大家所想的那样能给js动画带来性能上的大幅提升。虽然MDN和MSDN上对这个api的原理说明都让我觉得它确实是有用的,但实际测试的效果却并不能让我满意。也许各大浏览器厂商还会继续优化这个api的实现,使其能真正达到预期的效果吧。

BTW,其实到这里我自己都很怀疑是不是我的测试案例有问题?如果大家对测试案例有任何意见或建议,还请不吝赐教啊!

以上所有测试的运行环境为 Windows 7 Ultimate sp1 x64 + Chrome 25.0.1364.97 + Intel Core i3 530(2.93GHz) + 4G RAM

代码

 <!DOCTYPE html>
<html>
<head>
<style type="text/css">
html,body{height:100%;width:100%}
div{width:20px;height:20px;background-color:black;position:absolute;display:inline-block}
</style>
</head>
<body>
<div id="content" style="height:100%;width:100%;background-color:#979797;overflow:hidden;position:relative"></div>
<script type="text/javascript">
var cArray = new Array(); for (var i = 0; i < 1500; i++) {
var x = parseInt(Math.random() * document.body.clientWidth);
var y = parseInt(Math.random() * document.body.clientHeight);
var id = newGuid();
content.innerHTML += '<div id="' + id + '"></div>';
cArray.push(new Clock(x, y, 100, id));
} function Clock(x, y, r, id) {
this.start = new Date();
this.r = r;
this.x = x;
this.y = y;
this.offsetX = r;
this.offsetY = 0;
this.id = id;
this.draw = function(){
//update data
var timespan = new Date() - this.start;
var offsetR = ((timespan % 36000) % 720) / 360 * Math.PI;
this.offsetX = this.r * Math.cos(offsetR);
this.offsetY = this.r * Math.sin(offsetR);
//draw
var dom = document.getElementById(this.id);
dom.style.left = this.x + this.offsetX + 'px';
dom.style.top = this.y + this.offsetY + 'px'; //var that = this; //test case 01
//setTimeout(function(){that.draw()}, 40); //test case 01 - 1
//requestAnimationFrame(function(){that.draw()}); //test case 01 - 2
}
//this.draw(); //test case 01
} function renderLoop(){
for (var i = 0; i < cArray.length; i++) {
cArray[i].draw();
}
//setTimeout(renderLoop, 20); //test case 02 - 1
requestAnimationFrame(renderLoop); //test case 02 - 2
}
renderLoop(); //test case 02 function newGuid() {
var guid = "";
for (var i = 1; i <= 32; i++) {
var n = Math.floor(Math.random() * 16.0).toString(16);
guid += n;
if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
guid += "-";
}
return guid;
}
</script>
</body>
</html>

如需转载,请注明转自 http://www.cnblogs.com/silenttiger/archive/2013/06/19/3143785.html

欢迎关注我的微信公众号:老虎的小窝

requestAnimationFrame优势何在?的更多相关文章

  1. PostgreSQL 与 MySQL 相比,优势何在?【转】

    最近看到PostgreSQL话题比较多,就搜索了一下它与mysql的对比作者:知了链接:http://www.zhihu.com/question/20010554/answer/74037965来源 ...

  2. Dashboard究竟是什么,它在数据展示上的优势何在?

    ​相信很多人在做数据分析工作的时候都遇到这种情况,辛辛苦苦做出来的数据报表老板看了嫌弃不够直观.生动,客户看了嫌弃不够高大上.这个时候不妨尝试一下使用Dashboard来展示报表数据,可能有些人对Da ...

  3. PostgreSQL 与 MySQL 相比,优势何在?

    一. PostgreSQL 的稳定性极强, Innodb 等引擎在崩溃.断电之类的灾难场景下抗打击能力有了长足进步,然而很多 MySQL 用户都遇到过Server级的数据库丢失的场景——mysql系统 ...

  4. requestAnimationFrame小结

    背景 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout或者setInterval 来实现,css3 可以使用 transition 和 anima ...

  5. 【开源】OSharp框架解说系列(4):架构分层及IoC

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  6. 2015-01-16 .Net 中级软件工程师 笔试题

    一 C#方面 1.请简述多线程需要考虑的主要因素 答:1.线程管理 同一核上的两个线程不会以两倍的时长完成,可能需要用两倍再加10 %左右的时间来完成.与一个线程相比较的话,三个线程在同一核上想占用1 ...

  7. 分享SQL Server 2012/2014内存数据库,AlwaysOn,参考教材与网上总结

    Sql Server 2012 高可用性的几种方案的比较,AlwaysOn优势何在 对Sql Server 2012 高可用性与灾难恢复的几种方案的比较,复制,集群,镜像优劣何在,新生技术Always ...

  8. PetShop的系统架构设计

    <解剖PetShop>系列 一.PetShop的系统架构设计 http://www.cnblogs.com/wayfarer/archive/2007/03/23/375382.html ...

  9. Java基础之泛型——使用泛型链表类型(TryGenericLinkedList)

    控制台程序 定义Point类: public class Point { // Create a point from its coordinates public Point(double xVal ...

随机推荐

  1. Nodejs和npm入门使用

    目录 引子 何为node.js 和 npm 怎么使用node.js和npm 安装node.js & npm npm init 初始化项目(创建node.js模块) Package.json 属 ...

  2. QQ邮箱验证码

    人的记忆有时候跟鱼一样,只有七秒钟,短暂的时间! .NET  Web窗体实现忘记密码,使用QQ邮箱验证修改 一.首先设置一下发送个人或企业发送的邮箱 二.登录邮箱进行设置,如图:  三.关闭邮箱 四. ...

  3. Logstash和Flume-NG Syslog接收小测试

    目前在大规模日志处理平台中常见的日志采集器可以采用Logstash或Flume.这两种日志采集器架构设计理念基本相似,都采用采集-过滤处理-输出的方式.下面对这两种采集器Syslog接收性能做个简单测 ...

  4. php中查询时间

    在做查询过程中,例如要实现查上个月从第一天到最后一天的佣金(提成),那我们在程序实现过程中就要让程序在上个月的范围内查询,第一天是比较好办,但最后一天就不定,要去写段函数进行月份及年份判断来得出上个月 ...

  5. 利用NET HUNTER建立一个自动文件下载的网络接入点

    免责声明:本文旨在分享技术进行安全学习,禁止非法利用. 本文中我将完整的阐述如何通过建立一个非常邪恶的网络接入点来使得用户进行自动文件下载.整个过程中我将使用 Nexus 9 来运行Kali NetH ...

  6. jquery.form.js mvc 上传文件 layer 选择框与等待效果

    HTML <form role="form" id="form1"> <div class="form-group"> ...

  7. html5 js 游戏的一篇博客 貌似不错

    http://blog.csdn.net/lufy_legend/article/details/8888787

  8. Java 输入输出流总结

    1. 运用BufferedInputStream 读取文件流和BufferedOutputStream写文件流: protected static void writeFile2(String inp ...

  9. javascript:typeof与instanceof区别

    from:http://www.wxwdesign.cn/article/skills/javascript_typeof_instanceof.htm JavaScript中typeof和insta ...

  10. virtualbox+vagrant学习-2(command cli)-10-vagrant Port命令

    Port 格式: vagrant port [options] [name|id] 端口命令显示映射到主机端口的客户端口的完整列表 userdeMacBook-Pro:~ user$ vagrant ...