an ckick pictrue

吃饭不洗...segmentfault 专栏

关于setTimeout的那些冷知识

Issue链接更新于:2020-07-16

为什么 setTimeout 有最小时延 4ms ?

参考文章

首先:

setTimeout 规范由 whatwg 来维护

规范中存在这样两条:

  • 如果设置的 timeout 小于 0,则设置为 0
  • 如果嵌套的层级超过了 5 层,并且 timeout 小于 4ms,则设置 timeout 为 4ms。

而在浏览器实现端,做了调整,对于chrome

  • 第一条规则: timeout 小于 1,则设置为 1. 即 finalTime = Math.max(1, setTime);
  • 第二条规则: 规范要求是>5,而实现是>=5

为什么最小值是1,不是0??

  • 如果浏览器允许 0ms,会导致 JavaScript 引擎过度循环,也就是说如果浏览器架构是单进程的,那么可能网站很容易无响应。因为浏览器本身也是建立在 event loop 之上的,如果速度很慢的 JavaScript engine 通过 0ms timer 不断安排唤醒系统,那么 event loop 就会被阻塞。

为什么>=5 时,最小是4

  • it is a long story,具体就是当小于4时,会造成CPU持续运转,无法进入睡眠模式;

各个浏览器都未完全按规范实现,但主流浏览器基本与chrome 实现相似。

setTimeout 与 requestAnimationFrame 区别

requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行;

  • 在离屏情况下,当tab已经被切换(chrome针对这个有优化),或则动画已经被滚动到非可视区,setTimeout与setinterval仍然会计算更新动画,而requestAnimationFrame就会停止(懒惰优化策略);

  • setTimeout与setinterval只会根据他们的计算,认为需要更新动画,就去更新;而没有和屏幕本身的刷新同步;而requestAnimationFrame的动画是和屏幕整体刷新同步的;这种和屏幕不同步的更新,会导致不必要的计算,没有和侦更新同步的,会被丢弃,会更多的消耗cpu;

  • 当你的网页需要在一些不同的设备上运行时(fps不同),setTimeout与setinterval设置更新评率需要做更多的适配;

  • 页面多动画时,setTimeout的处理会比较复杂。

更多

等待被发现