requestAnimationFrame优势何在?

本文通过构造不同数量的动画,对比了requestAnimationFrame与setTimeout在动画渲染性能上的差异。实验结果显示,在特定条件下,requestAnimationFrame表现出更优的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大概半年前,无意中在网上看到一个新的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

代码

复制代码
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <style type="text/css">
 5         html,body{height:100%;width:100%}
 6         div{width:20px;height:20px;background-color:black;position:absolute;display:inline-block}
 7     </style>
 8 </head>
 9 <body>
10     <div id="content" style="height:100%;width:100%;background-color:#979797;overflow:hidden;position:relative"></div>
11     <script type="text/javascript">
12         var cArray = new Array();
13 
14         for (var i = 0; i < 1500; i++) {
15             var x = parseInt(Math.random() * document.body.clientWidth);
16             var y = parseInt(Math.random() * document.body.clientHeight);
17             var id = newGuid();
18             content.innerHTML += '<div id="' + id + '"></div>';
19             cArray.push(new Clock(x, y, 100, id));
20         }
21 
22         function Clock(x, y, r, id) {
23             this.start = new Date();
24             this.r = r;
25             this.x = x;
26             this.y = y;
27             this.offsetX = r;
28             this.offsetY = 0;
29             this.id = id;
30             this.draw = function(){
31                 //update data
32                 var timespan = new Date() - this.start;
33                 var offsetR = ((timespan % 36000) % 720) / 360 * Math.PI;
34                 this.offsetX = this.r * Math.cos(offsetR);
35                 this.offsetY = this.r * Math.sin(offsetR);
36                 //draw
37                 var dom = document.getElementById(this.id);
38                 dom.style.left = this.x + this.offsetX + 'px';
39                 dom.style.top = this.y + this.offsetY + 'px';
40 
41                 //var that = this;                                  //test case 01
42                 //setTimeout(function(){that.draw()}, 40);          //test case 01 - 1
43                 //requestAnimationFrame(function(){that.draw()});   //test case 01 - 2
44             }
45             //this.draw();                                          //test case 01
46         }
47 
48         function renderLoop(){
49             for (var i = 0; i < cArray.length; i++) {
50                 cArray[i].draw();
51             }
52             //setTimeout(renderLoop, 20);           //test case 02 - 1
53             requestAnimationFrame(renderLoop);      //test case 02 - 2
54         }
55         renderLoop();                               //test case 02
56 
57         function newGuid() {
58             var guid = "";
59             for (var i = 1; i <= 32; i++) {
60                 var n = Math.floor(Math.random() * 16.0).toString(16);
61                 guid += n;
62                 if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
63                     guid += "-";
64             }
65             return guid;
66         }
67     </script>
68 </body>
69 </html>
复制代码

 

热电制冷器利用塞贝克效应,通过电子在不同温度端点间的运动来实现热量转移,具体来说,当直流电流通过两种不同导电类型的半导体材料时,电流方向的一侧会吸收热量而另一侧会释放热量,从而产生冷却效果。这种现象称为珀尔帖效应,是热电制冷器工作原理的核心所在。 参考资源链接:[热电制冷技术:珀尔帖元件的原理与优势](https://wenku.youkuaiyun.com/doc/7xkwe36ygr?spm=1055.2569.3001.10343) 热电制冷器与传统的机械制冷(如压缩机式制冷)的主要区别在于工作原理和结构。机械制冷依赖于压缩机压缩制冷剂循环,通过改变制冷剂的物态(液态和气态)来吸收和释放热量。这种循环过程中伴随着机械运动,因此需要定期维护。而热电制冷器则无需任何运动部件,通过电流控制进行制冷,因此可靠性更高,维护更简便。 热电制冷器的优势主要体现在以下几个方面:1)结构紧凑,无运动部件,减少了故障点和维护需求;2)便于精确控制温度,适合对温度敏感的精密设备;3)可实现快速温度变化响应,便于即时调整制冷量;4)环保,没有制冷剂泄漏风险,且运行时几乎无噪音;5)适用范围广,尤其适合小空间或需要便携式制冷的场合。 设计一个基于热电效应的制冷系统需要考虑材料的选择、热电偶的设计、电流的控制以及热管理。选择适当的半导体材料和掺杂水平以优化热电性能,设计合理的热电偶结构以提高热电转换效率,通过电子控制系统精确控制电流方向和大小,以及确保良好的热接口和散热设计,都是实现高效温度控制的关键因素。 有关热电制冷技术更深入的了解,建议参考《热电制冷技术:珀尔帖元件的原理与优势》一书。该书详细探讨了热电制冷器的工作原理,优势,以及在实际应用中如何通过优化设计提高其性能。对于希望进一步研究热电制冷器的读者来说,这是一本不可多得的资源。 参考资源链接:[热电制冷技术:珀尔帖元件的原理与优势](https://wenku.youkuaiyun.com/doc/7xkwe36ygr?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值