closertb.github.io
closertb.github.io copied to clipboard
关于setTimeout的那些冷知识
为什么 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的处理会比较复杂。
更多
等待被发现