编写JavaScript动画时,您当然会使用setInterval(或重复的setTimeout)进行循环。但是在setInterval / setTimeout调用中使用的最佳延迟是什么?
在jQuery API page for the .animate() function中,用户“fbogner”说:
如果有人感兴趣:动画是使用setInterval“渲染”的,时间超过13毫秒。这很快! Chrome的最快间隔时间约为10毫秒。所有其他浏览器在20-30ms左右“采样”。
知道jQuery如何决定使用这个特定的号码吗?
开始赏金。我希望有了解Chromium或Firefox背后的源代码的人可以提供一些可能支持特定帧速率决策的硬性事实。或者可能是动画(或框架)列表及其延迟。我相信这为进行一些研究提供了一个有趣的机会。
有趣 - 我只是花时间查看Google的Pac-Man来源,看看他们做了什么。他们设置了一系列可能的FPS(90,45,30),从第一个开始,然后每帧检查帧的“慢度”(帧的数量超过其分配的时间)。如果慢度超过50ms 20次,则帧速率下降到列表中的下一个(90-> 45,45-> 30)。似乎帧速率从未提升,大概是因为游戏的寿命很短,所以编码就不值得。
哦,setInterval延迟当然设置为1000 /帧速率。事实上,它们使用setInterval而不是重复的setTimeouts。
我认为这种动态帧速率功能非常整洁!
答案 0 :(得分:17)
我冒昧地说,相当一部分网络用户正在使用以60Hz刷新的监视器,这意味着每16.66ms转换一帧。因此,要使显示器成为瓶颈,您需要生成速度超过16.66ms的帧。
有两个原因可以选择13ms这样的值。首先,浏览器需要一点时间来重新绘制屏幕(根据我的经验,从不低于1毫秒)。比如说,每15ms更新一次,这恰好是一个非常有趣的数字 - Windows上的标准计时器分辨率是15ms(参见John Resig's blog post)。我怀疑在各种各样的浏览器/操作系统中,写得很好的15ms动画看起来非常接近。
FWIW,fbogner 完全错误关于每隔20-30ms触发setInterval的非Chrome浏览器。我写了一个test来测量setInterval射击的速度,得到了这些数字:
答案 1 :(得分:5)
这个伪代码就是这个:
FPS_WANTED = 25
(just a number, it can be changed while executing, or it can be constant)
TIME_OF_DRAWING = 1000/FPS_WANTED
(this is in milliseconds, I believe it is accurate enough)
( should be updated when FPS_WANTED changes)
UntilTheUserLeavesTheDrawingApplication()
{
time1 = getTime();
doAnimation();
time2 = getTime();
animationTime = time2-time1;
if (animationTime > TIME_OF_DRAWING)
{
[the FPS_WANTED cannot be reached]
You can:
1. Decrease the number of FPS to see if a lower framerate can be achieved
2. Do nothing because you want to get all you can from the CPU
}
else
{
[the FPS can be reached - you can decide to]
1. wait(TIME_OF_DRAWING-animationTime) - to keep a constant framerate of FPS_WANTED
2. increase framerate if you want
3. Do nothing because you want to get all you can from the CPU
}
}
当然可以有各种变化,但这是在任何动画情况下都有效的基本算法。
答案 2 :(得分:3)
在为动画制作循环时,最好在循环速度和需要完成的工作之间找到平衡点。
例如,如果您想在一秒钟内在页面上滑动div,那么这是一个很好的效果和及时。你会跳过坐标并有一个相当快的循环时间,所以效果很明显,但不会跳跃。
所以这是一个反复试验的事情(通过考虑工作,时间和浏览器功能)。所以它不仅在一个浏览器上看起来很好。
答案 3 :(得分:2)
fbogner告诉的数字已经过测试。 浏览器将js-activity限制在一定程度,以便每次都可用。
如果您的javascript可以每5毫秒运行一次,那么浏览器运行时将更少的CPU时间来刷新渲染或对用户输入(点击)做出反应,因为javascript执行会阻止浏览器。
我认为chrome-devs允许你以比其他浏览器短得多的间隔运行你的javascript,因为他们的V8-Javascript-Engine编译JavaScript,因此它运行得更快,只要解释,浏览器就不会被阻止JS-代码。
但引擎不仅允许更短的时间间隔,开发人员已经测试了这是最短的间隔,允许短的间隔,并且不会阻止浏览器长时间
答案 4 :(得分:1)
不知道jQuery的间隔时间背后的原因,因为13ms转换为80fps非常快。在电影中使用的“标准”fps是25fps并且足够快以至于人眼不会注意到任何抖动。 25fps转换为40ms,所以回答你的问题:40ms以下的任何东西都足以制作动画。