-
Notifications
You must be signed in to change notification settings - Fork 22.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add scheduler.yield() #35960
base: main
Are you sure you want to change the base?
Add scheduler.yield() #35960
Conversation
Preview URLs
Flaws (1)Note! 4 documents with no flaws that don't need to be listed. 🎉 URL:
External URLs (1)URL:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM.
Have a few (non-blocking) comments where it could potentially be improved further.
@@ -23,15 +23,33 @@ In this page, we also include information about the {{domxref("Scheduling.isInpu | |||
|
|||
The Prioritized Task Scheduling API is available in both window and worker threads using the `scheduler` property on the global object. | |||
|
|||
The main API method is {{domxref('Scheduler.postTask()')}}, which takes a callback function ("the task") and returns a promise that resolves with the return value of the function, or rejects with an error. | |||
The main API methods are {{domxref('scheduler.postTask()')}} and {{domxref('scheduler.yield()')}}. `scheduler.postTask()` takes a callback function ("the task") and returns a promise that resolves with the return value of the function, or rejects with an error. `scheduler.yield()` turns any async function into a task by yielding the main thread to the browser for other work, with execution continuing when the returned promise is resolved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth calling out some more differences here?
- That
postTask
has more options for setting priority and/or aborting the task - But that
scheduler.yield
is simpler to use as can be added without wrapping code in a function.
|
||
#### `scheduler.postTask()` | ||
|
||
`scheduler.postTask()` creates a task with default priority [`user-visible`](#user-visible) that has a fixed priority and cannot be aborted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe:
`scheduler.postTask()` creates a task with default priority [`user-visible`](#user-visible) that has a fixed priority and cannot be aborted. | |
`scheduler.postTask()` creates a task with an optional priority (defaulted to [`user-visible`](#user-visible)) that cannot be aborted. |
And can it not be aborted? I thought that was one of the benefits of postTask
over yield
(see my comment above). What's https://developer.mozilla.org//en-US/docs/Web/API/Scheduler/postTask#aborting_tasks all about?
Or does this mean the default call can't be aborted (since it doesn't provide a signal
argument). If so this should be reworded (appreciate you didn't write the original, but still let's fix this while in here).
|
||
Long tasks can be broken up by awaiting `scheduler.yield()`. The function returns a promise, yielding the {{Glossary('main thread')}} to allow the browser to execute other pending work—like responding to user input—if needed. | ||
|
||
For instance, if a `change` event listener on a checkbox results in a lot of work to filter content and update the page, this means there will be no visual feedback to the user that the checkbox was checked until that work is complete. A `scheduler.yield()` can be inserted into the event listener to yield early so the checked state will be seen immediately, and then the heavier computation can be done when the yield returns. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid example. However, I worry about encouraging "no-op" yields.
Maybe should start with an example:
button.addEventListener("click", async () => {
// Provide feedback that the action was received, and is being processed
await scheduler.yield();
// Do longer processing
});
And then move on to your example: "It may also be sufficient to have the browser default actions provide that feedback. For instance, if a change
event listener on a checkbox..."
|
||
By default, `scheduler.yield()` is run with a [`'user-visible'`](/en-US/docs/Web/API/Prioritized_Task_Scheduling_API#user-visible) priority. However, the continuation from a `scheduler.yield()` has a slightly different behavior than `scheduler.postTask()` tasks of the same `priority`. | ||
|
||
`scheduler.yield()` enqueues its task at the front of a priority level's queue, while `scheduler.postTask()` tasks go at the end (in the spec, this is defined by a task queue's [effective priority](https://wicg.github.io/scheduling-apis/#scheduler-task-queue-effective-priority)). This means that with the same priority, the `scheduler.yield()` continuation will come first, allowing additional flexibility in how tasks can be scheduled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whhhattt! This is news to me!
Even more reason to use yield
over postTask
then!
@@ -23,15 +23,33 @@ In this page, we also include information about the {{domxref("Scheduling.isInpu | |||
|
|||
The Prioritized Task Scheduling API is available in both window and worker threads using the `scheduler` property on the global object. | |||
|
|||
The main API method is {{domxref('Scheduler.postTask()')}}, which takes a callback function ("the task") and returns a promise that resolves with the return value of the function, or rejects with an error. | |||
The main API methods are {{domxref('scheduler.postTask()')}} and {{domxref('scheduler.yield()')}}. `scheduler.postTask()` takes a callback function ("the task") and returns a promise that resolves with the return value of the function, or rejects with an error. `scheduler.yield()` turns any async function into a task by yielding the main thread to the browser for other work, with execution continuing when the returned promise is resolved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main API methods are {{domxref('scheduler.postTask()')}} and {{domxref('scheduler.yield()')}}. `scheduler.postTask()` takes a callback function ("the task") and returns a promise that resolves with the return value of the function, or rejects with an error. `scheduler.yield()` turns any async function into a task by yielding the main thread to the browser for other work, with execution continuing when the returned promise is resolved. | |
The main API methods are {{domxref('scheduler.postTask()')}} and {{domxref('scheduler.yield()')}}. `scheduler.postTask()` takes a callback function (the task) and returns a promise that resolves with the return value of the function, or rejects with an error. `scheduler.yield()` turns any async function into a task by yielding the main thread to the browser for other work, with execution continuing when the returned promise is resolved. |
The simplest form of the API is shown below. This creates a task with default priority [`user-visible`](#user-visible) that has a fixed priority and cannot be aborted. | ||
#### `scheduler.yield()` | ||
|
||
To break up long-runing JavaScript so it doesn't block the main thread, a `scheduler.yield()` can be inserted to temporarily yield the main thread back to the browser, which creates a task to continue execution where it left off. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To break up long-runing JavaScript so it doesn't block the main thread, a `scheduler.yield()` can be inserted to temporarily yield the main thread back to the browser, which creates a task to continue execution where it left off. | |
To break up long-running JavaScript tasks so they don'tt block the main thread, a call to `scheduler.yield()` can be inserted to temporarily yield the main thread back to the browser, which creates a task to continue execution where it left off. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this generally looks fine, but I added a couple of suggestions for prose.
} | ||
``` | ||
|
||
`scheduler.yield()` returns a promise that can be awaited for when execution can continue. This allows work that belongs in the same function to stay in the same function but without blocking the main thread the entire time the function runs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`scheduler.yield()` returns a promise that can be awaited for when execution can continue. This allows work that belongs in the same function to stay in the same function but without blocking the main thread the entire time the function runs. | |
`scheduler.yield()` returns a promise that can be awaited for when execution can continue. This allows work that belongs in the same function to stay in the same function, but without blocking the main thread the entire time the function runs. |
|
||
`scheduler.yield()` returns a promise that can be awaited for when execution can continue. This allows work that belongs in the same function to stay in the same function but without blocking the main thread the entire time the function runs. | ||
|
||
`scheduler.yield()` takes no arguments. The task that triggers its continuation has a default [`user-visible`](#user-visible) priority, but if a `scheduler.yield()` is run within a `scheduler.postTask()` task, it will [inherit the priority of the surrounding task](/en-US/docs/Web/API/Scheduler/yield#inheriting_task_priorities). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`scheduler.yield()` takes no arguments. The task that triggers its continuation has a default [`user-visible`](#user-visible) priority, but if a `scheduler.yield()` is run within a `scheduler.postTask()` task, it will [inherit the priority of the surrounding task](/en-US/docs/Web/API/Scheduler/yield#inheriting_task_priorities). | |
`scheduler.yield()` takes no arguments. The task that triggers its continuation has a default [`user-visible`](#user-visible) priority, but if `scheduler.yield()` is called within a `scheduler.postTask()` callback, it will [inherit the priority of the surrounding task](/en-US/docs/Web/API/Scheduler/yield#inheriting_task_priorities). |
|
||
The task can continue when the promise returned by the method is resolved. The priority for when the promise is resolved defaults to [`'user-visible'`](/en-US/docs/Web/API/Prioritized_Task_Scheduling_API#user-visible), but can inherit a different priority if the `yield()` occurs within a {{domxref('Scheduler.postTask')}}. | ||
|
||
Similarly, the continuation of work after the `yield()` can be aborted if it occurs within a `postTask()` task and the [task is aborted](/en-US/docs/Web/API/Scheduler/postTask#aborting_tasks). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, the continuation of work after the `yield()` can be aborted if it occurs within a `postTask()` task and the [task is aborted](/en-US/docs/Web/API/Scheduler/postTask#aborting_tasks). | |
Similarly, the continuation of work after the `yield()` can be aborted if it occurs within a `postTask()` callback, and the [task is aborted](/en-US/docs/Web/API/Scheduler/postTask#aborting_tasks). |
|
||
### Basic usage | ||
|
||
Long tasks can be broken up by awaiting `scheduler.yield()`. The function returns a promise, yielding the {{Glossary('main thread')}} to allow the browser to execute other pending work—like responding to user input—if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this glossary definition should be linked much earlier in the guide.
|
||
Long tasks can be broken up by awaiting `scheduler.yield()`. The function returns a promise, yielding the {{Glossary('main thread')}} to allow the browser to execute other pending work—like responding to user input—if needed. | ||
|
||
For instance, if a `change` event listener on a checkbox results in a lot of work to filter content and update the page, this means there will be no visual feedback to the user that the checkbox was checked until that work is complete. A `scheduler.yield()` can be inserted into the event listener to yield early so the checked state will be seen immediately, and then the heavier computation can be done when the yield returns. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For instance, if a `change` event listener on a checkbox results in a lot of work to filter content and update the page, this means there will be no visual feedback to the user that the checkbox was checked until that work is complete. A `scheduler.yield()` can be inserted into the event listener to yield early so the checked state will be seen immediately, and then the heavier computation can be done when the yield returns. | |
For instance, if a `change` event listener on a checkbox results in a lot of work to filter content and update the page, this means there will be no visual feedback to the user that the checkbox was checked until that work is complete. A `scheduler.yield()` can be inserted into the event listener to yield early so the checked state will be seen immediately, and then the remainder of the work can be done when the yield returns. |
Description
Chrome 129 adds
yield
method to the Scheduler interface. This PR adds reference documentation for the new method.Additional details