Javascript 为什么多个setTimeout()调用会导致如此多的延迟?

Javascript 为什么多个setTimeout()调用会导致如此多的延迟?,javascript,firefox,google-chrome,lag,Javascript,Firefox,Google Chrome,Lag,我有一个复杂的动画序列,涉及JavaScript中的淡入淡出和过渡。在这个由四个元素同时变化组成的序列中,每个元素都使用了setTimeout 在InternetExplorer9中测试,动画以实时速度工作(应该需要1.6秒,正好需要1.6秒)。任何其他浏览器都会严重滞后,动画时间为4秒(Firefox 3和4、Chrome、Opera),IE 8及以下版本大约为20秒 当所有其他浏览器都陷入泥潭时,IE9怎么能走得这么快? 我试图找到将元素合并为一个元素的方法,以便在任何给定时间都有一个set

我有一个复杂的动画序列,涉及JavaScript中的淡入淡出和过渡。在这个由四个元素同时变化组成的序列中,每个元素都使用了
setTimeout

在InternetExplorer9中测试,动画以实时速度工作(应该需要1.6秒,正好需要1.6秒)。任何其他浏览器都会严重滞后,动画时间为4秒(Firefox 3和4、Chrome、Opera),IE 8及以下版本大约为20秒

当所有其他浏览器都陷入泥潭时,IE9怎么能走得这么快?

我试图找到将元素合并为一个元素的方法,以便在任何给定时间都有一个setTimeout,但不幸的是,它经受不住任何干扰(例如在当前动画完成之前单击其他链接以启动新动画)

编辑:为了详细说明对评论的回应,以下是代码的概要:

link.onclick = function() {
    clearTimeout(colourFadeTimeout);
    colourFadeTimeout = setTimeout("colourFade(0);",25);

    clearTimeout(arrowScrollTimeout);
    arrowScrollTimeout = setTimeout("arrowScroll(0);",25);

    clearTimeout(pageFadeOutTimeout);
    pageFadeOutTimeout = setTimeout("pageFadeOut(0);",25);

    clearTimeout(pageFadeInTimeout);
    pageFadeInTimeout = setTimeout("pageFadeIn(0);",25);
}
这四个函数中的每一个都将淡入淡出进行一帧,然后在参数增加的情况下设置另一个超时,直到动画结束


你可以在(Username:knockknock;Password:goaway)上看到这个页面(它有声音和音乐,可以禁用,但是要注意!)-我的JavaScript非常混乱,因为我没有真正正确地组织它,但是它被注释了一点,所以希望你能看到它的大意。

好吧,这是很多JavaScript(尽管“惊人的四倍剂量”:

你启动了很多setTimeout序列,我不确定JS引擎在这方面的优化程度。特别是IE有几点:

  • 您的超时为25ms。这转换为40fps,这是通过javascript尝试实现的一个非常高的帧速率。特别是对于涉及可能触发回流的DOM操作的事情。将其增加到50或60。15fps对于您正在执行的动画类型来说应该足够流畅。您不想在这里显示视频,而只是mov在这一页上写些东西

  • 不要将字符串用作
    setTimeout()
    的第一个参数。特别是在您关心性能的情况下。这将迫使javascript在动画的每一帧重新编译字符串。请改用函数。如果需要传递参数,请使用匿名函数包装要执行的函数:

    setTimeout(function(){
        pageFadeIn(0)
    },50);
    
    在加载脚本时,这将只编译一次

  • 正如Ben所提到的,使用一个setTimeout来调度函数更便宜。因此,使用setInterval可能会提高代码的清晰度(也可能不会,这取决于您的编码风格)


  • 其他答案:

    编程javascript动画是关于优化和折衷的。可以在页面上以较小的速度制作很多东西的动画,但你需要知道如何正确操作,并决定牺牲什么。作为一个例子,我几年前写的一个演示实时策略游戏一次可以制作多少动画

    我为优化游戏所做的工作包括:

  • 《行走的士兵》只由两帧动画组成,我只是在两幅图像之间切换。但是效果非常令人信服。你不需要完美的动画,只要一个看起来令人信服的动画

  • 我对每件事都使用一个setInterval。它在CPU方面更便宜,也更容易管理。只需确定一个基本帧速率,然后安排不同的动画在不同的时间开始


  • 你能详细说明一下吗?动画本身是慢的,还是因为等待超时而在动画的不同部分之间有一段等待时间?另外,一些代码也会有所帮助。动画的四个部分是:(1)使用<代码>不透明度<代码>淡出当前页面,(2)使用<代码>不透明度<代码>淡入新页面,(3)使用<代码>背景色,(4)在导航栏上使用<代码>左侧的滚动指针(是的,这很过分,但主要是为了炫耀)。动画应以40FPS的速度运行(超时间隔为25ms),但在速度较慢的浏览器中,每一帧的时间至少是原来的两倍,并且会出现明显的跳跃。发布代码可能会让你感到痛苦,因为它现在太乱了……你可能错过了一个跳舞的宝宝,我认为在某个地方一次发生的事情太多了,这与
    设置超时
    几乎没有关系。你可能想使用这个p在IE9中推广卓越的Javascript引擎,但如果你对其他浏览器能够处理它感兴趣,你可能需要稍微降低效果。(或者以更好的方式进行。不过,我并不打算查看你凌乱的脚本以进行优化。:)我明天会尝试一下(因为现在是凌晨3点)然后让你知道结果如何。再次感谢你的回答。我不知道你可以将函数传递给setTimeout-这将使事情在将来变得更容易!我一定会让你知道它是否有效。我还会将帧速率减半(我确保所有动画都有一个二次方的帧数,因为这样可以轻松缩放并保持数字的完美精度,除非我弄错了)好的,一切都很顺利。Firefox仍然比较慢,但我认为这只是引擎本身在IE9中更好,因为它的速度远没有以前那么慢(现在只比应该的时间长了半秒)。非常感谢您的帮助-我不知道您可以将函数传递给setTimeout。这是一个非常好的答案(和示例)@slebetman您的答案上的链接不再可用。如果您仍然有,您可以重新发布您的来源吗?@UpTheCreek:40fps在2010年是非常高的帧速率-它会使IE6慢到爬行。是的,在2010年,我们仍然必须支持IE6和IE7
    setTimeout(function(){
        pageFadeIn(0)
    },50);