ChromiumのGoogle Groupsを眺めていたらsetTimeout()の実装で面白いものをみつけた.
Intent to Ship: Remove clamping of setTimeout(..., 0)
Summary
Calls to setTimeout(..., 0) were previously clamped to a 1 ms timeout for historical reason: https://bugs.chromium.org/p/chromium/issues/detail?id=402694, This is very old, http://trac.webkit.org/changeset/17156 appeared to add it (10/20/06).
This is actually a bug since there's no 1ms clamp in the spec, and which will cause scheduling error, e.g.
setTimeout(()=> console.log('1ms timeout'), 1);
setTimeout(()=> console.log('0ms timeout'), 0);
Outputs:
Chrome 87: 1ms timeout, 0ms timeout
Moreover, 1ms clamp may bring performance penalty.
出典) https://groups.google.com/a/chromium.org/g/blink-dev/c/HKPTp7C1LwY/m/kIbTxKSPAwAJ
要約すると...
setTimeout(..., 0)
は歴史的理由によって,1msのタイムアウトを含んでいるという.このポストではChromeに変更が加えられ,1msのタイムアウトを取り除く実装になったことがアナウンスされている.
歴史的な理由は,setTimeout(..., 0)
によるCPUの過剰な使用を避けるためだという.
実装の確認
1msの前は10msのタイムアウトが入っていたよう.tはミリ秒をあらわす.
Honor tiny timer intervals for JS timeouts as they are nested until a cutoff point is reached.
At that point clamp to 10ms to prevent excessive CPU usage.
出典) http://trac.webkit.org/changeset/17156/webkit
変更前
// Use a minimum interval of 10 ms to match other browsers.
double interval = t <= 10 ? 0.010 : t * 0.001;
変更後
// Use a minimum interval of 10 ms to match other browsers, but only once we've
// nested enough to notice that we're repeating.
double interval = max(0.001, t * 0.001);
if (interval < cMinimumTimerInterval && nestLevel >= cMaxTimerNestingLevel)
interval = cMinimumTimerInterval;
余談
Slackのtimesでつぶやいたら @malillu さんからsetInterval()
のネストは4msかかると教えてもらった.
Timers can be nested; after five such nested timers, however, the interval is forced to be at least four milliseconds.
出典) http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#timers
参考) setTimeout(...,0)などの使いドコロ - Qiita
↓setTimeout()なにもわからん.
setTimeout仕様クイズ | クイズメーカー - こたえてあそぶ・つくってあそぶ・クイズのプラットフォームサービス