JavaScript setTimeout()在重载情况下会变慢

JavaScript setTimeout()在重载情况下会变慢,javascript,settimeout,Javascript,Settimeout,我创建了一个脚本,可以淡出元素的背景色。我使用setTimeout()每5毫秒对颜色进行一次增量更改。如果我一次只淡出一件东西的背景颜色,脚本效果会很好,但是如果我有50个元素,我会一次全部淡出,速度会比5毫秒慢得多,因为所有并发setTimeout()同时运行。例如,如果一次淡入50个元素,通常应在1秒内执行的淡入可能需要30秒 有没有办法克服这个问题 以下是脚本,以防有人有想法: function fadeBackground(elementId, start, end, time) {

我创建了一个脚本,可以淡出元素的背景色。我使用setTimeout()每5毫秒对颜色进行一次增量更改。如果我一次只淡出一件东西的背景颜色,脚本效果会很好,但是如果我有50个元素,我会一次全部淡出,速度会比5毫秒慢得多,因为所有并发setTimeout()同时运行。例如,如果一次淡入50个元素,通常应在1秒内执行的淡入可能需要30秒

有没有办法克服这个问题

以下是脚本,以防有人有想法:

function fadeBackground(elementId, start, end, time) {
    var iterations = Math.round(time / 5);

    var step = new Array(3);

    step[0] = (end[0] - start[0]) / iterations;
    step[1] = (end[1] - start[1]) / iterations;
    step[2] = (end[2] - start[2]) / iterations;

    stepFade(elementId, start, step, end, iterations);
}

function stepFade(elementId, cur, step, end, iterationsLeft) {
    iterationsLeft--;

    document.getElementById(elementId).style.backgroundColor
        = "rgb(" + cur[0] + "," + cur[1] + "," + cur[2] + ")";

    cur[0] = Math.round(end[0] - step[0] * iterationsLeft);
    cur[1] = Math.round(end[1] - step[1] * iterationsLeft);
    cur[2] = Math.round(end[2] - step[2] * iterationsLeft);

    if (iterationsLeft > 1) {
        setTimeout(function() {
            stepFade(elementId, cur, step, end, iterationsLeft);
        }, 5);
    }
    else {
        document.getElementById(elementId).style.backgroundColor 
            = "rgb(" + end[0] + "," + end[1] + "," + end[2] + ")";
    }
}
它是这样使用的:

fadeBackground("myList", [98,180,232], [255,255,255], 1000);
这是一篇来自谷歌的文章,作者讨论了他们在Gmail定时器方面的工作。他们发现,如果使用大量且快速的计时器,则使用单个高频计时器比使用多个计时器要快

您可以有一个每5毫秒触发一次的计时器,并将所有需要淡入淡出的元素添加到数据结构中,以跟踪它们在淡入淡出过程中的位置。然后,您的一个计时器可以查看该列表,并在每次触发时对每个元素执行下一次淡入淡出


另一方面,您是否尝试过使用类库或而不是滚动自己的动画框架?他们的开发人员在优化这类操作方面投入了大量工作。

首先,您的脚本没有考虑到最小超时通常是10-15毫秒,具体取决于浏览器。你可以看到。在里面你会找到一个流行浏览器的表格和一个测量它的程序链接,这样你就可以自己验证这个声明了。很抱歉,每5毫秒迭代一次是一厢情愿的想法

其次,计时器不是中断。它们没有魔力——它们不能中断浏览器中运行的任何东西并执行有效负载。相反,它们将被延迟,直到运行的代码完成,浏览器获得控制权和运行计时器的能力。淡入50个元素需要时间,我打赌这需要5毫秒以上,特别是考虑到浏览器的整个延迟模型:更新DOM,浏览器将在某个时间点更新其视觉表示

我想以一个积极的音符结束:

  • 与其淡出50个单独的元素,不如尝试将它们分组并淡出它们的父元素,这样会更快
  • 在UI方面要更有创意。试着想出一个解决方案,它不需要同时淡出许多独立的元素
  • 在围绕这些假设进行设计之前,请始终验证您的背景假设是否正确
  • 如果可以,尝试以现代浏览器为目标。根据我个人的经验,Google Chrome非常适合计时器,它的JavaScript引擎(V8)速度非常快

我认为一个计时器可能是最好的选择,但我担心必须实施更改。:)实际上,我决定自己玩,因为我使用jQuery来制作()动画,但实际上它在大约10%的时间里都没有褪色。不幸的是,这是一个不可接受的错误率。我来看看这篇文章。多谢!呵呵。Stackoverflow也有“无法设置动画”的问题。