-
Notifications
You must be signed in to change notification settings - Fork 49.4k
Don't rely on Scheduler.didTimeout to tell us that SyncBatched is synchronous #19469
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
Conversation
Tasks with SyncBatchedPriority — used by Blocking Mode — should always be rendered by the `peformSyncWorkOnRoot` path, not `performConcurrentWorkOnRoot`. Currently, they go through the `performConcurrentWorkOnRoot` callback. Then, we check `didTimeout` to see if the task expired. Since SyncBatchedPriority translates to ImmediatePriority in the Scheduler, `didTimeout` is always `true`, so we mark it as expired. Then it exits and re-enters in the `performSyncWorkOnRoot` path. Aside from being overly convoluted, we shouldn't rely on Scheduler to tell us that SyncBatchedPriority work is synchronous. We should handle that ourselves. This will allow us to remove the `didTimeout` check. And it further decouples us from the Scheduler priority, so we can eventually remove that, too.
6570dea
to
1fb18e2
Compare
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 1fb18e2:
|
Details of bundled changes.Comparing: 96ac799...1fb18e2 react-dom
react-reconciler
react-art
react-test-renderer
react-native-renderer
Size changes (experimental) |
Details of bundled changes.Comparing: 96ac799...1fb18e2 react-dom
react-native-renderer
react-reconciler
react-art
react-test-renderer
Size changes (stable) |
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.
LGMT
performSyncWorkOnRoot.bind(null, root), | ||
); | ||
} else if (newCallbackPriority === SyncBatchedLanePriority) { | ||
newCallbackNode = scheduleCallback( |
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.
Are we intentionally not using scheduleSyncCallback
like in the block above?
What if other sync work is already scheduled, do we want this to always come after?
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 naming is confusing. scheduleSyncCallback
adds stuff to a special queue that can be flushed synchronously without going through Scheduler. It's used for SyncLane and expired updates.
"sync" in performSyncWorkOnRoot
means that it doesn't yield to the main thread and it doesn't check Suspense timeouts (though that part might change), so it has fewer checks than concurrent updates.
SyncBatched is kind of a mix between sync mode and concurrent mode. It doesn't yield to the main thread, but it does go through Scheduler (i.e. is scheduled by postMessage), hence the weird naming conflicts.
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 see, thanks for explaining 👍
Tasks with SyncBatchedPriority — used by Blocking Mode — should always be rendered by the
performSyncWorkOnRoot
path, notperformConcurrentWorkOnRoot
.Currently, they go through the
performConcurrentWorkOnRoot
callback. Then, we checkdidTimeout
to see if the task expired. Since SyncBatchedPriority translates to ImmediatePriority in the Scheduler,didTimeout
is alwaystrue
, so we mark it as expired. Then it exits and re-enters in theperformSyncWorkOnRoot
path.Aside from being overly convoluted, we shouldn't rely on Scheduler to tell us that SyncBatchedPriority work is synchronous. We should handle that ourselves.
This will allow us to remove the
didTimeout
check. And it further decouples us from the Scheduler priority, so we can eventually remove that, too.