你知道setInterval与setTimeout之间的性能差异吗

很早之前在《高级程序设计》里看到,setIntervalsetTimeout之间的性能是有很大差异的,但当时只是简单的记住了,并没有自己尝试,今天刚好遇到一个相关性能优化的需求,就深入测试和研究一下两者之间的差异吧。

性能差异简述

setIntervalsetTimeout 都是 JavaScript 中常用的定时器函数,两者在实现定时器效果时有一些差别,也会影响到它们的性能表现。

setInterval 是一个反复执行的定时器函数,它会每隔一定时间(由第二个参数指定的毫秒数)执行一次回调函数。而 setTimeout 则是一次性的定时器函数,它会在指定的时间后执行一次回调函数。

性能比较上,setInterval 的性能可能会更低,因为它的回调函数每隔一定时间就会被执行一次,如果回调函数的执行时间比时间间隔还长,那么会导致多个回调函数同时进行,从而导致性能问题。而 setTimeout 则可以通过递归的方式实现反复执行的效果,这样每次只有一个回调函数正在执行,相对来说更容易控制性能。

另外,在浏览器进行页面渲染时,setInterval 会通过不停地执行回调函数来更新页面,这会增加浏览器的负担;而 setTimeout 则可以在页面空闲的时候执行回调函数,从而避免了这个问题。

综上所述,尽管 setIntervalsetTimout 都可以实现定时器效果,但在性能上,setTimeout 更加可控,因此在一些相对复杂的定时器场景下,使用 setTimeout 可以获得更好的性能表现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(() => {
// 使用 setInterval 实现计数器
let start = Date.now();
let count = 0;

let timer1 = setInterval(() => {
count++;
if (count >= 1000) {
clearInterval(timer1);
let end1 = Date.now();
console.log(`setInterval: ${end1 - start} ms`);
}
}, 1);
})();

(() => {
// 使用 setTimeout 实现计数器
let start2 = Date.now();
let count2 = 0;
let timer2 = null;
function updateCount() {
count2++;
if (count2 >= 1000) {
clearTimeout(timer2);
let end2 = Date.now();
console.log(`setTimeout: ${end2 - start2} ms`);
} else {
timer2 = setTimeout(updateCount, 1);
}
}
updateCount();
})();

本文永久链接: https://www.mulianju.com/performance-difference-of-timers/