JavaScript setTimeout() 在重负载下变慢
-
05-07-2019 - |
题
我创建了一个可以淡化元素背景颜色的脚本。我使用 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);
其他提示
首先,您的脚本没有考虑到最小超时通常为 10-15 毫秒,具体取决于浏览器。你可以看到 我关于这个主题的帖子. 。在里面,您会找到流行浏览器的表格以及测量该浏览器的程序的链接,以便您可以自己验证该声明。我很遗憾地说,每 5 毫秒迭代一次是一个一厢情愿的想法。
其次,定时器不是中断。它们没有什么魔力——它们无法中断浏览器中正在运行的任何内容并执行其有效负载。相反,它们将被推迟,直到运行的代码完成并且浏览器重新获得控制权和运行计时器的能力。淡入淡出 50 个元素需要时间,我敢打赌它会超过 5 毫秒,特别是如果您考虑到浏览器的整个延迟模型:你更新 DOM,浏览器就会在某个时间点更新它的视觉表示。
我想以积极的态度结束本文:
- 不要淡出 50 个单独的元素,而是尝试将它们分组并淡出其父元素 - 这样会更快。
- 在 UI 上更具创意。尝试想出一个解决方案,该解决方案不需要立即淡出大量独立元素。
- 在围绕它们进行设计之前,请务必验证您的背景假设是否正确。
- 如果可以的话,尝试针对现代浏览器。根据我个人的经验,Google Chrome 的计时器非常好,而且它的 JavaScript 引擎 (V8) 非常快。
除了其他答案之外,这里还有John Resig关于计时器的优秀文章: http://ejohn.org/blog/how-javascript-timers-work/
不隶属于 StackOverflow