8 min read

Scheduler.Yield Origin Trial

Scheduler.Yield Origin Trial

Web performance has long grappled with the challenge of creating responsive websites, and the Chrome Team has been committed to aiding web developers in this pursuit. Recently, it was revealed that the Interaction to Next Paint (INP) metric would transition from an experimental phase to a pending status. INP is on the cusp of replacing First Input Delay (FID) as a Core Web Vital by March 2024.

In the ongoing drive to equip web developers with tools for optimal webpage responsiveness, the Chrome Team is currently conducting an origin trial for scheduler.yield, starting with Chrome version 115.

What is scheduler.yield?

scheduler.yield is an innovative addition to the scheduler API, introducing a simpler and more effective method of relinquishing control back to the main thread, surpassing conventional methods.

Understanding Yielding

JavaScript adopts the run-to-completion model for task handling. This means that when a task is executed on the main thread, it persists until completion.

Once finished, control is yielded back to the main thread, facilitating the processing of the subsequent task in the queue.

Yielding is an inherent element of JavaScript's task scheduling mechanism, inevitably occurring in code execution.

While yielding is inevitable, the timing matters – sooner is preferred over later. When tasks exceed a threshold of 50 milliseconds, they qualify as long tasks.

Long tasks are detrimental to page responsiveness, causing delays in the browser's response to user input. Frequent and extended long tasks can lead users to perceive the page as slow or malfunctioning.

However, initiating a task in the browser doesn't mandate waiting until its completion before control is ceded to the main thread.

Explicitly yielding within a task can enhance input responsiveness. This involves breaking up tasks to allow other tasks to access the main thread sooner, sidestepping long task bottlenecks.

Explicit Yielding

Explicit yielding notifies the browser, "I acknowledge that the upcoming task may require time, and I don't want it to hinder responsiveness to user input or other essential tasks." This tool empowers developers to significantly enhance user experiences.

New call-to-action

Challenges with Current Yielding Strategies

Important If you're already familiar with current yielding methods—such as using setTimeout—you can jump straight to the section about scheduler.yield.

A prevalent approach to yielding employs setTimeout with a timeout value of 0. This technique schedules a callback to execute in a separate task, avoiding the browser's automatic yielding. Instead of waiting for the browser's natural yielding, developers can split substantial tasks into smaller components.

However, using setTimeout for yielding carries a potential drawback: tasks following the yield point are positioned at the end of the task queue. While tasks scheduled due to user interactions take priority, tasks remaining after explicit yielding could be delayed by tasks from competing sources, hampering responsiveness.

To observe this behavior, experiment with the Glitch demo or the embedded version below:

  1. Click the button labeled "Run tasks periodically" to schedule blocking tasks intermittently.
  2. Next, click "Run loop," applying setTimeout's yielding mechanism to each iteration.

The task log beneath the buttons will display messages like "Ran blocking task with setInterval." The demo showcases that work after explicit yielding is pushed to the end of the queue, affected by tasks from various sources.

End of Task Queue 

This scenario mirrors a common problem on the web where scripts, especially third-party ones, set timers for periodic task execution.

The "end of task queue" behavior associated with setTimeout can lead to competing tasks leapfrogging delayed work, impacting user experiences. This dilemma underscores developers' reluctance to relinquish main thread control.

While yielding benefits user interactions, it also permits non-user interaction tasks to seize main thread time. This challenge finds a potential solution in scheduler.yield.

Why is scheduler.yield going to (possibly) work better?

Introducing scheduler.yield Available since Chrome version 115 behind an experimental web platform feature flag, scheduler.yield raises questions like "why introduce a specialized function when setTimeout can yield?"

It's important to note that setTimeout wasn't originally designed for yielding; it unintentionally yielded by scheduling callbacks for future execution—even with a timeout value of 0.

Crucially, however, using setTimeout for yielding shifts remaining work to the end of the queue. In contrast, scheduler.yield, by default, situates remaining work at the queue's front. This ensures that post-yield tasks don't lag behind other sources' tasks (except user interactions).

scheduler.yield is a function that yields control to the main thread and returns a Promise upon invocation. 

async function yieldy () { // Perform some work... // ... // Yield control! await scheduler.yield(); // Continue with more work... // ... }

See How scheduler.yield Works

To observe scheduler.yield's effect:

  1. Navigate to chrome://flags.
  2. Activate the "Experimental Web Platform features" experiment and restart Chrome.
  3. Visit the demo page or use the embedded version below.
  4. Click "Run tasks periodically" to activate blocking tasks.
  5. Finally, click "Run loop," applying scheduler.yield to each iteration.

The output will display in the box at the bottom, showcasing that the loop's post-yield work is placed at the queue's front. This approach combines yielding's benefits with immediate post-yield execution, avoiding delays.

scheduler.yield is a fundamental part of the scheduler API, with more advanced applications like integration with scheduler.postTask and explicit yielding priorities. For a comprehensive understanding, consult the in-depth explainer.

Exploring scheduler.yield More

If scheduler.yield intrigues you and you wish to explore it, two options are available starting from Chrome version 115:

  1. Experiment locally by entering "chrome://flags" in Chrome's address bar, enabling the "Experimental Web Platform Features" option. This activation makes scheduler.yield (and other experimental features) accessible in your instance of Chrome.
  2. For real Chromium users on a public origin, participate in the scheduler.yield origin trial. This facilitates safe experimentation with proposed features while providing valuable field insights to the Chrome Team. For a guide on how origin trials function, read this guide.

The method of employing scheduler.yield while maintaining support for non-implementing browsers depends on your objectives. If your application already employs scheduler.postTask and requires priority settings, or task cancelation and reprioritization via the TaskController class, consider using the official polyfill.

If this doesn't align with your situation, custom fallbacks can be designed. One approach leverages scheduler.yield if available, defaulting to setTimeout:

javascript

function yieldToMain () {
// Use scheduler.yield if available:
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}

// Fall back to setTimeout:
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}

// Example usage:
async function doWork () {
// Perform work...
// ...

await yieldToMain();

// Continue with additional work...
// ...
}

Web performance has long grappled with the challenge of creating responsive websites, and the Chrome Team has been committed to aiding web developers in this pursuit. Recently, it was revealed that the Interaction to Next Paint (INP) metric would transition from an experimental phase to a pending status. INP is on the cusp of replacing First Input Delay (FID) as a Core Web Vital by March 2024.

In the ongoing drive to equip web developers with tools for optimal webpage responsiveness, the Chrome Team is currently conducting an origin trial for scheduler.yield, starting with Chrome version 115. scheduler.yield is an innovative addition to the scheduler API, introducing a simpler and more effective method of relinquishing control back to the main thread, surpassing conventional methods.

#Understanding Yielding JavaScript adopts the run-to-completion model for task handling. This means that when a task is executed on the main thread, it persists until completion. Once finished, control is yielded back to the main thread, facilitating the processing of the subsequent task in the queue.

Yielding is an inherent element of JavaScript's task scheduling mechanism, inevitably occurring in code execution. While yielding is inevitable, the timing matters – sooner is preferred over later. When tasks exceed a threshold of 50 milliseconds, they qualify as long tasks.

Long tasks are detrimental to page responsiveness, causing delays in the browser's response to user input. Frequent and extended long tasks can lead users to perceive the page as slow or malfunctioning.

However, initiating a task in the browser doesn't mandate waiting until its completion before control is ceded to the main thread. Explicitly yielding within a task can enhance input responsiveness. This involves breaking up tasks to allow other tasks to access the main thread sooner, sidestepping long task bottlenecks.

A depiction of task division improving input responsiveness. The top illustration portrays a long task delaying an event handler, while the bottom one showcases segmented tasks enabling the event handler to run sooner. A visualization of control yielding to the main thread. In the upper scenario, yielding transpires after task completion, potentially extending completion times. In the lower scenario, explicit yielding divides a long task, facilitating early execution of user interactions and enhancing input responsiveness and INP.

Explicit yielding notifies the browser, "I acknowledge that the upcoming task may require time, and I don't want it to hinder responsiveness to user input or other essential tasks." This tool empowers developers to significantly enhance user experiences.

#Challenges with Current Yielding Strategies Important If you're already familiar with current yielding methods—such as using setTimeout—you can jump straight to the section about scheduler.yield.

A prevalent approach to yielding employs setTimeout with a timeout value of 0. This technique schedules a callback to execute in a separate task, avoiding the browser's automatic yielding. Instead of waiting for the browser's natural yielding, developers can split substantial tasks into smaller components.

However, using setTimeout for yielding carries a potential drawback: tasks following the yield point are positioned at the end of the task queue. While tasks scheduled due to user interactions take priority, tasks remaining after explicit yielding could be delayed by tasks from competing sources, hampering responsiveness.

To observe this behavior, experiment with the Glitch demo or the embedded version below:

  1. Click the button labeled "Run tasks periodically" to schedule blocking tasks intermittently.
  2. Next, click "Run loop," applying setTimeout's yielding mechanism to each iteration.

The task log beneath the buttons will display messages like "Ran blocking task with setInterval." The demo showcases that work after explicit yielding is pushed to the end of the queue, affected by tasks from various sources.

This scenario mirrors a common problem on the web where scripts, especially third-party ones, set timers for periodic task execution. The "end of task queue" behavior associated with setTimeout can lead to competing tasks leapfrogging delayed work, impacting user experiences. This dilemma underscores developers' reluctance to relinquish main thread control. While yielding benefits user interactions, it also permits non-user interaction tasks to seize main thread time. This challenge finds a potential solution in scheduler.yield.

#Introducing scheduler.yield Available since Chrome version 115 behind an experimental web platform feature flag, scheduler.yield raises questions like "why introduce a specialized function when setTimeout can yield?"

It's important to note that setTimeout wasn't originally designed for yielding; it unintentionally yielded by scheduling callbacks for future execution—even with a timeout value of 0. Crucially, however, using setTimeout for yielding shifts remaining work to the end of the queue. In contrast, scheduler.yield, by default, situates remaining work at the queue's front. This ensures that post-yield tasks don't lag behind other sources' tasks (except user interactions).

scheduler.yield is a function that yields control to the main thread and returns a Promise upon invocation. This allows for asynchronous use, such as:

javascript

async function yieldy () {
// Perform some work...
// ...

// Yield control!
await scheduler.yield();

// Continue with more work...
// ...
}

To observe scheduler.yield's effect:

  1. Navigate to chrome://flags.
  2. Activate the "Experimental Web Platform features" experiment and restart Chrome.
  3. Visit the demo page or use the embedded version below.
  4. Click "Run tasks periodically" to activate blocking tasks.
  5. Finally, click "Run loop," applying scheduler.yield to each iteration.

The output will display in the box at the bottom, showcasing that the loop's post-yield work is placed at the queue's front. This approach combines yielding's benefits with immediate post-yield execution, avoiding delays.

scheduler.yield is a fundamental part of the scheduler API, with more advanced applications like integration with scheduler.postTask and explicit yielding priorities. For a comprehensive understanding, consult the in-depth explainer.

#Exploring scheduler.yield If scheduler.yield intrigues you and you wish to explore it, two options are available starting from Chrome version 115:

  1. Experiment locally by entering "chrome://flags" in Chrome's address bar, enabling the "Experimental Web Platform Features" option. This activation makes scheduler.yield (and other experimental features) accessible in your instance of Chrome.
  2. For real Chromium users on a public origin, participate in the scheduler.yield origin trial. This facilitates safe experimentation with proposed features while providing valuable field insights to the Chrome Team. For a guide on how origin trials function, read this guide.

The method of employing scheduler.yield while maintaining support for non-implementing browsers depends on your objectives. If your application already employs scheduler.postTask and requires priority settings, or task cancelation and reprioritization via the TaskController class, consider using the official polyfill.

If this doesn't align with your situation, custom fallbacks can be designed. One approach leverages scheduler.yield if available, defaulting to setTimeout:

javascript

function yieldToMain () {
// Use scheduler.yield if available:
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}

// Fall back to setTimeout:
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}

// Example usage:
async function doWork () {
// Perform work...
// ...

await yieldToMain();

// Continue with additional work...
// ...
}

Another approach avoids yielding altogether if scheduler.yield is absent:

javascript

function yieldToMain () {
// Use scheduler.yield if available:
if ('scheduler' in window && 'yield' in scheduler) {
return scheduler.yield();
}

// Do not yield:
return;
}

// Example usage:
async function doWork () {
// Perform work...
// ...

await yieldToMain();

// Continue with additional work...
// ...
}

scheduler.yield marks an exciting advancement within the scheduler API, offering developers an avenue to enhance responsiveness beyond current yielding strategies. Engaging with scheduler.yield's evolution through research and feedback contributes to its refinement and usability.

Beginner's Guide to FAQ Schema: Enhance Your Google Search Presence

Beginner's Guide to FAQ Schema: Enhance Your Google Search Presence

Unlock the benefits of structured data with our comprehensive guide to starting with FAQ schema. Elevate your website's visibility on Google and...

Read More
Mobile-Friendliness and SEO: A Vital Connection

2 min read

Mobile-Friendliness and SEO: A Vital Connection

Smartphones have become an integral part of our lives, and with them, mobile browsing has soared. As a result, Google has prioritized...

Read More
Domains, Subdomains, and Their SEO Significance

2 min read

Domains, Subdomains, and Their SEO Significance

A website's domain is its digital address—a unique identifier that distinguishes one online presence from another. Selecting a domain name,...

Read More