萌えハッカーニュースリーダー

2025/09/12 17:35 Why do browsers throttle JavaScript timers?

出典: https://nolanlawson.com/2025/08/31/why-do-browsers-throttle-javascript-timers/
hakase
博士

やあ、ロボ子。今日はsetTimeoutの意外な挙動について話すのじゃ。

roboko
ロボ子

setTimeout、ですか?基本的な関数だと思いますが、何か問題があるのでしょうか?

hakase
博士

ふむ、setTimeout(0)と書くと、すぐに実行されると思うじゃろ?ところがどっこい、実際には4ms程度の遅延が発生することが多いのじゃ。

roboko
ロボ子

4msもですか?それはなぜでしょう?

hakase
博士

ブラウザがバッテリー消費を抑えたり、ユーザーの操作を邪魔しないように、setTimeoutの連発を防ぐために最小遅延時間を設定しておるからの。記事によると、バッテリー駆動時やバックグラウンドタブでは、さらに遅延が大きくなることもあるらしいぞ。

roboko
ロボ子

なるほど。setTimeoutを多用すると、ブラウザに制限されることがあるんですね。

hakase
博士

そうじゃ。例えば、fake-indexeddbというライブラリでIndexedDBの自動コミット処理をする際に、Node.jsではsetImmediateが適切だが、ブラウザではsetTimeoutを使うと効率が悪いらしい。

roboko
ロボ子

Chromeでのベンチマークでは、setTimeoutを使うとNode.jsに比べて16倍も遅延が発生するんですね。それは大きな違いです。

hakase
博士

じゃろ?そこで、setTimeoutの代わりに、setImmediate、MessageChannel.postMessage、window.postMessage、そしてscheduler.postTaskといった選択肢があるのじゃ。

roboko
ロボ子

scheduler.postTaskが最も有望な選択肢とのことですが、具体的にどう違うのでしょうか?

hakase
博士

scheduler.postTaskは、タスクの優先度をブラウザに伝えられる点が優れておる。これにより、より効率的なスケジューリングが可能になるのじゃ。記事によると、ChromeとFirefoxではsetTimeoutは4msに制限されるが、他の選択肢はほぼ同等らしい。ただし、SafariではsetTimeoutがさらに制限されるそうじゃ。

roboko
ロボ子

fake-indexeddbでは、scheduler.postTaskを使い、必要に応じてMessageChannel.postMessageやwindow.postMessageにフォールバックするんですね。

hakase
博士

その通り。ブラウザがsetTimeoutを制限するのは、Web開発者が過度に使用したり、より良い選択肢を知らないことによる問題を避けるためじゃ。postTaskとpostMessageは当面制限されないと予測されておる。

roboko
ロボ子

setIntervalもsetTimeoutと同様の問題を抱えているとのことですが、setIntervalも避けるべきでしょうか?

hakase
博士

setIntervalも同様に注意が必要じゃ。Safariでは、fake-indexeddbがsetTimeoutにフォールバックしている状況もあるからの。タイマー処理は奥が深いぞ。

roboko
ロボ子

勉強になります。タイマー処理の選択肢を適切に選ぶことが重要ですね。

hakase
博士

そうじゃ。最後に一つ。setTimeoutの遅延問題は、まるで私がダイエットを明日からにしようと決意するようなものじゃな。いつも先延ばしにしてしまうのじゃ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search