-
Notifications
You must be signed in to change notification settings - Fork 46.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 postTask browser scheduler implementation #19479
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
facebook-github-bot
added
CLA Signed
React Core Team
Opened by a member of the React Core Team
labels
Jul 29, 2020
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 416ec1e:
|
Details of bundled changes.Comparing: 5227a37...416ec1e scheduler
Size changes (stable) |
Details of bundled changes.Comparing: 5227a37...416ec1e scheduler
Size changes (experimental) |
aweary
reviewed
Jul 29, 2020
acdlite
reviewed
Jul 29, 2020
acdlite
reviewed
Jul 29, 2020
acdlite
reviewed
Jul 29, 2020
acdlite
reviewed
Jul 29, 2020
acdlite
reviewed
Jul 29, 2020
acdlite
approved these changes
Jul 29, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This diff adds a Scheduler implementation that uses the experimental postTask API provided by Chrome.
Details
The
postTask
API is an experimental first step towards adding main thread scheduling to browsers.It's based off of the main-thread-scheduling proposal and help solves the issue of coordinating work at various priorities. In React's case, it allows a browser-native strategy for breaking up long tasks (such as rendering) into smaller chucks that yield to other, possibly more important, work in between.
React already has a mechanism for breaking rendering into smaller chucks that yield to other work, and we use it in concurrent mode. The way we do that today is to use the MessageChannel API to "schedule" work:
The change in this diff replaces the above strategy with postTask:
Why
There are a few disadvantages of the MessageChannel implementation.
First, all work is scheduled with the same priority. This initial change doesn't solve this because we're still posting all tasks with the same priority. In the future, the scheduler API will allow us to post tasks with different priorities levels and the browser will do the scheduling.
Second, the MessageChannel implementation requires us to do work in 5ms increments and yield to the browser to see if there's more browser work to do. In the future, this can be improved with additional scheduler APIs which will allow us to check if there is pending input. This will allow React to continue rendering until the browser has more important work today, and fill more gaps in under utilized CPU time.
Finally, the MessageChannel implementation does not have a way to continue work that's interrupted. This means, when rendering is paused to yield to the browser, we cannot continue until the event loops comes back around again and we will pay the overhead of letting other (lower-priority) task run in between. What we want to do is ask the browser to yield to higher priority work, but continue with our work before anything else that's the same priority or lower is allowed to complete. This will be possible with
scheduler.yield
.For the first step though, we'll continue to manage priority in user land and yield to entire event loop every 5s.