Wie du an den Main Thread yieldest, um den INP zu verbessern
Nutze scheduler.yield(), um Long Tasks aufzuteilen und deine Seiten reaktionsschnell zu halten.
Yield to the main thread
Stell dir einen romantischen Film vor. Der Schauplatz ist ein französischer Marktplatz im Zentrum eines kleinen Dorfes. Die Straßen sind voller Paare, die Kaffee trinken, Croissants essen und Blumen kaufen. Stell dir nun vor, was passiert, wenn immer nur ein Käufer etwas von einem Verkäufer kaufen kann. Alle anderen müssen warten. Der Bäcker wird mit Anfragen überhäuft. Beim Floristen bricht Streit aus. Der romantische Spaziergang wird zu einer frustrierenden Wartezeit.
Genau das passiert auf einer Website, wenn zu viel los ist.
Zuletzt geprüft von Arjen Karel im März 2026
Warum yielding für den INP wichtig ist
Der main thread eines Browsers steuert alle wichtigen Prozesse: das Parsen von HTML und CSS, die Ausführung von JavaScript, die Verarbeitung von Input-Events wie Klicks und Scrollen, und das visuelle Rendering. Er arbeitet nach einem Single-Thread-Modell. Er führt also immer nur einen Task gleichzeitig aus. Startet ein Task, führt der Browser ihn bis zum Ende aus. Er stoppt nicht. Kein anderer Task kommt an die Reihe, bis der aktuelle fertig ist. Das nennt man blocking the main thread.
Blocking the main thread ist die Hauptursache für schlechte Interaction to Next Paint (INP) Werte. Klickt ein Besucher auf einen Button und dein JavaScript blockiert den main thread für 200 ms, kann der Browser keine Antwort rendern, bis das Skript beendet ist. Die processing time-Phase des INP misst genau diese Verzögerung. Laut dem 2025 Web Almanac liegt die mediane Total Blocking Time auf Mobilgeräten bei 1.916 ms. Das ist ein Anstieg von 58 % gegenüber dem Vorjahr. Das sind fast 2 Sekunden, in denen der Browser nicht auf Nutzereingaben reagieren kann.
Eine Lösung dafür ist das yielding an den main thread. Yielding ist eine Technik, bei der long tasks in mehrere kleine Tasks aufgeteilt werden. Das ermöglicht es dem Browser, zwischenzeitlich wichtigere Arbeit zu erledigen, wie die Reaktion auf Nutzereingaben.
Long tasks und blocking period: Dauert ein Task länger als 50 Millisekunden, wird er als long task eingestuft. Alles über dieser 50-Millisekunden-Grenze ist die „blocking period“ des Tasks. Teilst du diese long tasks in kleinere Stücke auf, bleibt der Browser reaktionsfähig. Das gilt auch bei rechenintensiven Operationen.
Alte yielding-Strategien
Vor der Prioritized Task Scheduling API gab es 4 Wege, um an den main thread zu yielden. Alle haben Einschränkungen.
- setTimeout(): Die häufigste Strategie.
setTimeout()mit einer Verzögerung von 0 fügt den Task ans Ende der Warteschlange an. Andere Tasks laufen zuerst. Das Problem: Tasks können nur ans Ende der Warteschlange geschoben werden. Andere Skripte können sich vordrängeln, bevor dein Code weiterläuft. VerschachteltesetTimeout()-Aufrufe erzwingen zudem eine minimale Verzögerung von 5 ms nach fünf Runden. - requestAnimationFrame(): Reiht eine Funktion zur Ausführung vor dem nächsten Repaint des Browsers ein. Oft kombiniert mit
setTimeout(). So laufen Callbacks sicher nach dem nächsten Layout-Update. Nicht für yielding gedacht, sondern für Animationen. - requestIdleCallback(): Eignet sich am besten für unkritische Tasks mit niedriger Priorität. Sie laufen während der Leerlaufzeit des Browsers. Die Einschränkung: Es gibt keine Garantie, dass geplante Tasks auf einem ausgelasteten main thread zeitnah (oder überhaupt) laufen.
- isInputPending(): Prüft auf ausstehende Nutzereingaben und yieldet nur, wenn eine Eingabe erkannt wird. Google empfiehlt diesen Ansatz nicht mehr. Er kann falsche Negative liefern. Zudem ignoriert er andere leistungskritische Arbeiten wie Animationen und Rendering-Updates.
scheduler.yield()
Die Einschränkungen dieser Methoden waren ein Problem für das Chrome-Team. Besonders, weil viele Seiten beim INP durchfallen. Um das zu lösen, haben sie scheduler.yield() entwickelt. Das ist eine neue API, die Entwickler sofort an den main thread yielden lässt. Die Task-Reihenfolge ändert sich nicht und es gibt keine zusätzliche Komplexität.
scheduler.yield() ist seit Chrome 129 stabil (September 2024). Alle großen Browser außer Safari unterstützen es jetzt.
Code-Beispiel
Da Safari scheduler.yield() noch nicht unterstützt, nutze einen fallback auf setTimeout():
function yieldToMain() {
if ('scheduler' in window && 'yield' in window.scheduler) {
return window.scheduler.yield();
}
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
} Die Funktion yieldToMain() prüft, ob window.scheduler.yield existiert. Falls ja, nutzt sie die native API. Falls nicht, fällt der Code auf setTimeout() zurück. Das entspricht dem von Google empfohlenen Muster.
Für Projekte, die die vollständige Prioritized Task Scheduling API (inklusive scheduler.postTask() und TaskController) benötigen, pflegt Google Chrome Labs einen offiziellen Polyfill.
Praxisbeispiel: Verbesserung der Suche mit yieldToMain()
So kann yieldToMain() das Sucherlebnis für deine Nutzer verbessern.
Die Funktion handleSearch() aktualisiert zuerst den Button-Inhalt. Das gibt sofortiges Feedback, dass eine Suche läuft. Dann yieldet sie. So kann der Browser das Update rendern. Als Nächstes ruft fetchData() die Suchdaten ab und updateHTML(data) zeigt die Ergebnisse an. Ein weiteres yieldToMain() sorgt für ein schnelles Layout-Update. Schließlich werden weniger wichtige Tasks während der Leerlaufzeit des Browsers geplant. Beachte: Ich habe vor requestIdleCallback() nicht geyieldet. Es läuft ohnehin nur, wenn der main thread frei ist.
async function handleSearch() {
/* quickly update the button content after submitting */
updateButtonToPending();
/* Yield to Main */
await yieldToMain();
/* fetch data and update html */
const data = await fetchData();
updateHTML(data);
/* Yield to Main again */
await yieldToMain();
/* some functions should only run during browser idle time */
requestIdleCallback(sendDataToAnalytics);
} Ein weiteres praktisches Beispiel zeigt, wie du dieses yielding-Muster bei dataLayer Pushes nutzt. So verhinderst du, dass Analytics-Skripte Interaktionen blockieren.
Warum scheduler.yield() besser ist
setTimeout() fügt verschobene Tasks ans Ende der Warteschlange an. scheduler.yield() pausiert die Ausführung und setzt die Fortsetzung an den Anfang der Warteschlange. Dein Code läuft weiter, sobald Arbeiten mit höherer Priorität (wie die Verarbeitung von Input-Callbacks) abgeschlossen sind. Das ist der entscheidende Unterschied. Du kannst an den main thread yielden, ohne das Risiko, dass sich andere Skripte vordrängeln.

scheduler.yield() ist für die Zusammenarbeit mit der Prioritized Task Scheduling API konzipiert. Beim Aufruf innerhalb eines scheduler.postTask()-Callbacks erbt scheduler.yield() die Prioritätsstufe des Tasks. Diese Kombination gibt dir eine präzise Kontrolle darüber, wie dein JavaScript priorisiert wird und wann es yieldet.
Browser-Support
scheduler.yield() wird von 71,5% der Browser weltweit unterstützt:
- Chrome 129+ und Edge 129+: stabil seit September 2024
- Firefox 142+: stabil seit August 2025
- Safari: nicht unterstützt, kein angekündigter Zeitplan
Der setTimeout() fallback in der obigen yieldToMain()-Funktion stellt sicher, dass dein Code in allen Browsern funktioniert. Safari-Nutzer erhalten das alte Verhalten. Fortsetzungen landen am Ende der Warteschlange. Die Seite yieldet trotzdem. Wenn der Browser-Support wächst, erhalten mehr Nutzer automatisch die schnellere Fortsetzung.
Blockieren Drittanbieter-Skripte den main thread komplett, ist das Zurückstellen dieser Skripte der bessere erste Schritt. Yielding hilft, wenn dein eigener Code viel Arbeit leisten muss. So bleibt der Browser zwischen den Code-Blöcken reaktionsfähig.
Um zu überprüfen, ob yielding deinen INP in der Praxis verbessert, überwache deine Seiten mit Real User Monitoring. Lab-Tools wie Lighthouse messen die Total Blocking Time. Aber nur field data zeigt den tatsächlichen INP, den deine Besucher erleben.
Dein Lighthouse-Score zeigt nicht das ganze Bild.
Deine Besucher sitzen auf Android-Geräten im 4G-Netz. Ich analysiere, was die tatsächlich sehen.
RUM-Daten auswerten