Hoe je yieldt naar de main thread om INP te verbeteren (Kopie)

Gebruik scheduler.yield() om long tasks op te breken en je pagina's responsief te houden.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-07-10

Yield naar de main thread

Stel je een romantische film voor. Het decor is een kleine Franse markt in het midden van een klein dorp. De straten zijn gevuld met stelletjes die koffie drinken, croissants eten en bloemen kopen. Stel je nu voor wat er gebeurt als slechts één koper tegelijk iets van een verkoper kan kopen, terwijl alle anderen op hun beurt moeten wachten. De bakker wordt overspoeld met verzoeken, er breken ruzies uit bij de bloemist en de romantische wandeling verandert in een frustrerende wachttijd.

Nou... dat is ongeveer wat er op een website gebeurt als het te druk wordt.

Laatst beoordeeld door Arjen Karel in maart 2026

Waarom yielding belangrijk is voor INP

De main thread van een browser handelt alle belangrijke processen af: HTML en CSS parsen, JavaScript uitvoeren, input events zoals klikken en scrollen afhandelen, en visueel renderen. Het draait op een single-threaded model, wat betekent dat het maar één taak tegelijk kan uitvoeren. Als een taak begint, voert de browser deze volledig uit en stopt niet tot deze klaar is. Er wordt geen andere taak ingepland totdat de huidige taak is afgerond. Dit noemen we de main thread blokkeren.

De main thread blokkeren is de belangrijkste oorzaak van slechte Interaction to Next Paint (INP) scores. Als een bezoeker op een knop klikt en je JavaScript de main thread 200ms blokkeert, kan de browser geen reactie tonen totdat het script klaar is. De processing time fase van INP meet precies deze vertraging. Volgens de 2025 Web Almanac is de mediane Total Blocking Time op mobiel 1.916ms, een stijging van 58% ten opzichte van vorig jaar. Dat is bijna 2 seconden waarin de browser niet kan reageren op gebruikersinvoer.

Een manier om dit op te lossen is door te yielden naar de main thread. Yielding is een techniek waarbij long tasks worden opgedeeld in meerdere kleinere taken. Hierdoor kan de browser tussendoor belangrijker werk afhandelen, zoals reageren op gebruikersinvoer.

Long tasks en blocking period: Als een taak langer dan 50 milliseconden duurt, wordt deze geclassificeerd als een long task. Alles boven die drempel van 50 milliseconden staat bekend als de "blocking period" van de taak. Door deze long tasks op te splitsen in kleinere stukken blijft de browser responsief, zelfs bij rekenintensieve operaties.

Oude yielding strategieën

Voor de Prioritized Task Scheduling API waren er 4 manieren om te yielden naar de main thread. Allemaal hebben ze beperkingen.

  • setTimeout(): De meest voorkomende strategie. setTimeout() met een vertraging van 0 voegt de taak toe aan het einde van de wachtrij, waardoor andere taken eerst kunnen draaien. Het probleem: taken kunnen alleen naar het einde van de wachtrij worden geschoven. Andere scripts kunnen dus voorpiepen voordat je code verdergaat. Geneste setTimeout() calls leggen ook een minimale vertraging van 5ms op na vijf rondes.
  • requestAnimationFrame(): Zet een functie in de wachtrij om uit te voeren voor de volgende repaint van de browser. Wordt vaak gecombineerd met setTimeout() om ervoor te zorgen dat callbacks worden ingepland na de volgende layout update. Niet ontworpen voor yielding, maar voor animatiewerk.
  • requestIdleCallback(): Het meest geschikt voor niet-kritieke taken met lage prioriteit die kunnen draaien tijdens de idle time van de browser. De beperking: er is geen garantie dat ingeplande taken snel (of überhaupt) draaien op een drukke main thread.
  • isInputPending(): Controleert op onverwerkte gebruikersinvoer en yieldt alleen als er invoer wordt gedetecteerd. Google raadt deze aanpak niet meer aan. Het kan false negatives opleveren en houdt geen rekening met ander prestatiekritiek werk, zoals animaties en rendering updates.

scheduler.yield()

De beperkingen van deze methoden waren een zorg voor het Chrome team, vooral omdat veel sites de INP norm niet halen. Om dit op te lossen bouwden ze scheduler.yield(): een nieuwe API waarmee ontwikkelaars direct naar de main thread kunnen yielden zonder de taakvolgorde om te gooien of complexiteit toe te voegen.

scheduler.yield() is stabiel gelanceerd in Chrome 129 (september 2024) en wordt nu ondersteund door alle grote browsers, behalve Safari.

Codevoorbeeld

Omdat Safari scheduler.yield() nog niet ondersteunt, gebruik je een fallback naar setTimeout():

function yieldToMain() {
  if ('scheduler' in window && 'yield' in window.scheduler) {
    return window.scheduler.yield();
  }
  return new Promise((resolve) => {
    setTimeout(resolve, 0);
  });
}

De yieldToMain() functie controleert of window.scheduler.yield bestaat. Zo ja, dan gebruikt het de native API. Zo niet, dan valt de code terug op setTimeout(). Dit komt overeen met het patroon dat Google aanbeveelt.

Voor projecten die de volledige Prioritized Task Scheduling API nodig hebben (inclusief scheduler.postTask() en TaskController), onderhoudt Google Chrome Labs een officiële polyfill.

Praktijkvoorbeeld: zoeken verbeteren met yieldToMain()

Hier zie je hoe yieldToMain() de zoekervaring voor je gebruikers kan verbeteren.

De handleSearch() functie updatet eerst de inhoud van de knop om direct feedback te geven dat er gezocht wordt. Daarna yieldt het zodat de browser die update kan renderen. Vervolgens haalt fetchData() zoekgegevens op en toont updateHTML(data) de resultaten. Een volgende yieldToMain() zorgt voor een snelle layout update. Tot slot worden minder belangrijke taken ingepland tijdens de idle time van de browser. Let op dat ik niet heb geyield voor requestIdleCallback(), omdat dit toch pas draait als de main thread idle is.

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);
}

Voor een ander praktijkvoorbeeld, bekijk hoe je hetzelfde yield-patroon gebruikt bij dataLayer pushes om te voorkomen dat analytics scripts interacties blokkeren.

Waarom scheduler.yield() beter is

In tegenstelling tot setTimeout(), dat uitgestelde taken aan het einde van de wachtrij toevoegt, pauzeert scheduler.yield() de uitvoering en plaatst het vervolg aan het begin van de wachtrij. Je code gaat verder zodra werk met een hogere prioriteit (zoals het afhandelen van input callbacks) is afgerond. Dit is het belangrijkste verschil: je kunt yielden naar de main thread zonder het risico dat andere scripts voorpiepen voordat je code verdergaat.

yielding timeline

scheduler.yield() is ook ontworpen om samen te werken met de Prioritized Task Scheduling API. Wanneer je het aanroept binnen een scheduler.postTask() callback, neemt scheduler.yield() het prioriteitsniveau van de taak over. Deze combinatie geeft je fijnmazige controle over hoe je JavaScript wordt geprioriteerd en wanneer het yieldt.

Browserondersteuning

scheduler.yield() wordt wereldwijd door 71,5% van de browsers ondersteund:

  • Chrome 129+ en Edge 129+: stabiel sinds september 2024
  • Firefox 142+: stabiel sinds augustus 2025
  • Safari: niet ondersteund, geen tijdlijn aangekondigd

De setTimeout() fallback in de yieldToMain() functie hierboven zorgt ervoor dat je code in alle browsers werkt. Safari gebruikers krijgen het oude gedrag waarbij vervolgtaken achteraan in de wachtrij komen, maar de pagina yieldt nog steeds. Naarmate de browserondersteuning groeit, krijgen meer gebruikers automatisch de snellere hervatting.

Als het probleem is dat scripts van derden de main thread volledig blokkeren, is het uitstellen van die scripts een betere eerste stap dan yielding. Yielding helpt wanneer je eigen code veel werk moet verzetten, maar je wilt dat de browser tussen de blokken door responsief blijft.

Om te verifiëren dat yielding je INP in de praktijk verbetert, monitor je je pagina's met Real User Monitoring. Lab tools zoals Lighthouse meten Total Blocking Time, maar alleen field data toont de daadwerkelijke INP die je bezoekers ervaren.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Ik krijg sites door de Core Web Vitals.

500K+ pagina's voor grote Europese uitgevers en e-commerce. Ik schrijf de fixes en check ze in de echte data.

Zo werk ik
Hoe je yieldt naar de main thread om INP te verbeteren (Kopie) Core Web Vitals Hoe je yieldt naar de main thread om INP te verbeteren (Kopie)