大概半年前,无意中在网上看到一个新的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. Yarn遭到挖矿病毒攻击

    测试环境在阿里云上暴露出了公网端口,前一段时间CDH集群原本是开启了Kerberos认证,但是因为大家反映使用麻烦,所以就又关闭了Kerberos. 最近几天大家普遍反映测试环境上hive和hdfs ...

  2. BZOJ4891:[TJOI2017]龙舟(Pollard-Rho,exgcd)

    Description 加里敦大学有一个龙舟队,龙舟队有n支队伍,每只队伍有m个划手,龙舟比赛是一个集体项目,和每个人的能力息息相关,但由于龙舟讲究配合,所以评价队伍的能力的是一个值c = (b1*b ...

  3. 【bzoj 4066】 简单题

    题目 显然这就是让我们在二维上数个点 如果没有强制在线就随便做啦,扫描线+主席树应该是最好的选择 但是现在强制在线并且卡了树套树的空间,于是只能上\(kdt\)了 我们还是维护一下每个子树分割出来的矩 ...

  4. BZOJ2694:Lcm——包看得懂/看不懂题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2694 Description 对于任意的>1的n gcd(a, b)不是n^2的倍数 也就是说 ...

  5. Odoo发送短信

    转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9281581.html 一:阿里云短信服务注册 1:开通短信业务:实名认证的个人用户是免费开通:企业用户需要提供 ...

  6. [19/05/03-星期五] GOF23_模式总结

    总结:

  7. zoc license code

    点击导航栏上的zoc-about zoc,然后: 点击enter license: 然后输入内容即可: part A:  51698/01027/34713 part B:  00937 还有很多其他 ...

  8. boost的初步了解

    本章介绍了 Boost C++ 库 Asio,它是异步输入输出的核心. 名字本身就说明了一切:Asio 意即异步输入/输出. 该库可以让 C++ 异步地处理数据,且平台独立. 异步数据处理就是指,任务 ...

  9. P1437 [HNOI2004]敲砖块

    题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...

  10. springboot activiti 整合项目框架源码 shiro 安全框架 druid 数据库连接池

     官网:www.fhadmin.org 工作流模块--------------------------------------------------------------------------- ...