setTimeout
setTimeout(code, millseconds) 用于延时执行参数指定的代码,如果在指定的延迟时间之前,你想取消这个执行,那么直接用clearTimeout(timeoutId)来清除任务,timeoutID 是 setTimeout 时返回的;
setInterval
setInterval(code, millseconds)用于每隔一段时间执行指定的代码,永无停歇,除非你反悔了,想清除它,可以使用 clearInterval(intervalId),这样从调用 clearInterval 开始,就不会在有重复执行的任务,intervalId 是 setInterval 时返回的;
虽然你在setInterval的里指定的周期是100毫秒,但它并不能保证两个函数之间调用的间隔一定是一百毫秒
1 | setInterval(function () { |
如果func执行的时间很长,超过了100ms

如果队列中的第二个函数时在第450毫秒处结束的话,在第500毫秒时,它会继续执行下一轮func,也就是说这之间的间隔只有50毫秒,而非周期100毫秒
想保证每次执行的间隔应该怎么办?用setTimeout
1 | var i = 1 |
requestAnimationFrame
requestAnimationFrame(code),一般用于动画,与 setTimeout 方法类似,区别是 setTimeout 是用户指定的,而 requestAnimationFrame 是浏览器刷新频率决定的,requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
怎么停止requestAnimationFrame?cancelAnimationFrame()接收一个参数 requestAnimationFrame默认返回一个id,cancelAnimationFrame只需要传入这个id就可以停止了。
示例:
1 |
|
requestIdleCallback
当关注用户体验,不希望因为一些不重要的任务(如统计上报)导致用户感觉到卡顿的话,就应该考虑使用requestIdleCallback。因为requestIdleCallback回调的执行的前提条件是当前浏览器处于空闲状态。
示例:
1 | requestIdelCallback(myNonEssentialWork); |
我们所看到的网页,都是浏览器一帧一帧绘制出来的,通常认为FPS为60的时候是比较流畅的,而FPS为个位数的时候就属于用户可以感知到的卡顿了,那么一帧里面浏览器都要做哪些事情

一帧包含了用户的交互、js的执行、以及requestAnimationFrame的调用,布局计算以及页面的重绘等工作,假如某一帧里面要执行的任务不多,一帧的的时间内就完成了上述任务的话,那么这一帧就会有一定的空闲时间,这段时间就恰好可以用来执行requestIdleCallback的回调。

由于requestIdleCallback利用的是帧的空闲时间,所以就有可能出现浏览器一直处于繁忙状态,导致回调一直无法执行,那么这种情况我们就需要在调用requestIdleCallback的时候传入第二个配置参数timeout了
示例:
1 | requestIdleCallback(myNonEssentialWork, { timeout: 2000 }); |
但是需要注意的就是这个API兼容性不好。
参考
http://qingbob.com/difference-between-settimeout-setinterval/
https://segmentfault.com/a/1190000020639465?utm_source=tag-newest