- In JavaScript wird
setTimeout(0) in der Praxis oft nicht sofort ausgeführt, sondern mit einer Mindestverzögerung von 4 ms, was eine grundlegende Browser-Beschränkung zur Verhinderung von Missbrauch ist
- Solche Einschränkungen sollen verhindern, dass Websites Timer wahllos missbrauchen und dadurch Akkuverbrauch oder schlechtere Interaktionen verursachen; im Akkubetrieb kann die Grenze auf 16 ms steigen, in Hintergrund-Tabs sogar auf 1 Sekunde
- Entwickler haben verschiedene alternative Timer-APIs genutzt, um die Grenzen von
setTimeout zu umgehen, darunter setImmediate, MessageChannel.postMessage, window.postMessage und scheduler.postTask
- Reale Benchmark-Ergebnisse zeigen, dass in Chrome und Firefox das 4-ms-Clamping greift, während
MessageChannel und scheduler.postTask nahezu ohne Verzögerung arbeiten; Safari drosselt setTimeout noch stärker
- Im Kern geht es um das Gleichgewicht zwischen dem Schutz der Nutzererfahrung und der Freiheit von Entwicklern; derzeit etabliert sich die Scheduler API als standardisierte Lösung, doch bei Missbrauch könnte eine neue Browser-Intervention eingeführt werden
Hintergrund der setTimeout-Beschränkung
Entstehung anderer Timer-APIs
setImmediate: nur in IE und altem Edge unterstützt, faktisch eingestellt
MessageChannel.postMessage: überträgt Aufgaben über einen separaten Kanal an den Event Loop
window.postMessage: gute Performance, aber Risiko von Kollisionen mit anderen Skripten
scheduler.postTask: in modernen Browsern unterstützt und als stabilste Option bewertet
Benchmark-Ergebnisse (MacBook Pro 2021, 101 Wiederholungen)
- Chrome 139:
setTimeout 4.2 ms, scheduler.postTask 0 ms
- Firefox 142:
setTimeout 4.72 ms, scheduler.postTask 0.01 ms
- Safari 18.4:
setTimeout 26.73 ms, MessageChannel 0.52 ms, window.postMessage 0.05 ms
Fallbeispiel fake-indexeddb
- IndexedDB möchte Transaktionen direkt nach dem Ende der Mikrotasks des Event Loops automatisch committen
setImmediate in Node.js ist dafür ideal, aber im Browser ist setTimeout ineffizient
- Ein Vorgang, der in Chrome 300 ms dauert, dehnt sich im Browser auf bis zu 4,8 Sekunden aus
- Als Lösung wird standardmäßig
scheduler.postTask verwendet und aus Kompatibilitätsgründen MessageChannel/window.postMessage als Fallback übernommen
Debatte um Browser-Interventionen
- Eine Seite argumentiert, Timer müssten begrenzt werden, damit Entwickler vor sich selbst geschützt werden
- Die andere Seite fordert, Freiheit zu gewährleisten, damit Entwickler selbst messen und optimieren können
- Letztlich greifen Browser nach dem Prinzip „Nutzer zuerst“ ein, um Missbrauch zu verhindern
- Die Scheduler API versucht beide Positionen zu vereinen, indem sie Entwicklern eine feinere Kontrolle über Aufgaben gibt und zugleich auf die Rendering-Pipeline des Browsers abgestimmt ist
Ausblick
postTask und postMessage werden vermutlich vorerst ohne Drosselung bestehen bleiben
- Werden jedoch hohe Prioritäten wie
user-blocking missbraucht, sind erneute Eingriffe möglich
- Langfristig könnte eine weitere alternative API wie
scheduler2 nötig werden
Noch keine Kommentare.