-
Notifications
You must be signed in to change notification settings - Fork 47.9k
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
Synchronously flush the transition lane scheduled in a popstate event #26025
Conversation
@@ -259,6 +259,8 @@ type BaseFiberRootProperties = { | |||
pooledCache: Cache | null, | |||
pooledCacheLanes: Lanes, | |||
|
|||
forceSync: boolean, |
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.
It's not really a "forced" sync because it just an best-effort attempt. This could easily be confused with the API called ReactDOM.flushSync(...)
which is more like a force.
This would be more like attemptEagerTransition
. I don't think you should necessarily need this flag though with the new refactoring because once we schedule an eager microtask all the time, you can just do the work right there if you check for it.
if (shouldAttemptEagerTransition()) performWorkOnRoot()
A lot of things will be a lot simpler with that model.
@@ -1469,7 +1478,7 @@ function performSyncWorkOnRoot(root: FiberRoot) { | |||
flushPassiveEffects(); | |||
|
|||
let lanes = getNextLanes(root, NoLanes); | |||
if (!includesSyncLane(lanes)) { | |||
if (!includesSyncLaneOrForceSync(lanes, root)) { |
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.
Instead of using performSyncWorkOnRoot for this, I wonder if you can just use performConcurrentWorkOnRoot without yielding. That way you don't have to mess with the lanes and other special cases for sync.
We already have cases for performing concurrent work without yielding.
react/packages/react-reconciler/src/ReactFiberWorkLoop.js
Lines 1047 to 1052 in a48e54f
// We disable time-slicing in some cases: if the work has been CPU-bound | |
// for too long ("expired" work, to prevent starvation), or we're in | |
// sync-updates-by-default mode. | |
// TODO: We only check `didTimeout` defensively, to account for a Scheduler | |
// bug we're still investigating. Once the bug in Scheduler is fixed, | |
// we can remove this, since we track expiration ourselves. |
ffb7566
to
1bceba2
Compare
Comparing: 72c890e...b340309 Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: Expand to show
|
1bceba2
to
638cd73
Compare
cd4e4cc
to
f5622fa
Compare
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 adding a test for the behavior where the transition can’t finish synchronously without triggering a fallback?
f5622fa
to
f642605
Compare
I'm not sure what would the expected behavior be when that happens. Maybe we can address it in a follow up PR. |
My understanding of the original goal was that if it can't finish the transition synchronously then the transition should suspend and not trigger any fallbacks. So it would fail to finish synchronously but the fallback behavior would be the same as if it didn't try for the eager transition. That's why it is called "should attempt eager transition" not "should force eager transition" or something. It's a nice to have for the common case so that browser scroll restoration, etc. works correctly but if for some reason the data isn't available then it would do the async transition. However my knowledge may be out of date so definitely defer to others. Also I don't understand how that intersects with Either way, it seems like an important aspect of the behavior here so I think it would be good to encode it in a test. |
The thinking is that it's more important for it to be synchronous than to avoid a fallback in this case because 1) it needs to be sync in order for the browser's scroll restoration mechanism to work 2) during a back navigation it's likely the data is cached so it probably won't suspend the important stuff anyway. However, if something suspends and there's no Suspense boundary above that can handle it, this trick isn't going to work regardless, so the thinking was we would fall back to the regular transition behavior (give up and change it back to async). This PR doesn't implement that but it's not as urgent as the main fix and we can add that later. |
I need this for another feature I'm working on so I'm going to go ahead and merge it, if that's alright |
…#26025) <!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary Browsers restore state like forms and scroll position right after the popstate event. To make sure the page work as expected on back or forward button, we need to flush transitions scheduled in a popstate synchronously, and only yields if it suspends. This PR adds a new HostConfig method to check if `window.event === 'popstate'`, and `scheduleMicrotask` if a transition is scheduled in a `PopStateEvent`. ## How did you test this change? yarn test DiffTrain build for [d121c67](d121c67)
…te event (facebook#26025)" This reverts commit d121c67.
…#26025) <!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary Browsers restore state like forms and scroll position right after the popstate event. To make sure the page work as expected on back or forward button, we need to flush transitions scheduled in a popstate synchronously, and only yields if it suspends. This PR adds a new HostConfig method to check if `window.event === 'popstate'`, and `scheduleMicrotask` if a transition is scheduled in a `PopStateEvent`. ## How did you test this change? yarn test
…facebook#26025) <!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary Browsers restore state like forms and scroll position right after the popstate event. To make sure the page work as expected on back or forward button, we need to flush transitions scheduled in a popstate synchronously, and only yields if it suspends. This PR adds a new HostConfig method to check if `window.event === 'popstate'`, and `scheduleMicrotask` if a transition is scheduled in a `PopStateEvent`. ## How did you test this change? yarn test
…#26025) <!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary Browsers restore state like forms and scroll position right after the popstate event. To make sure the page work as expected on back or forward button, we need to flush transitions scheduled in a popstate synchronously, and only yields if it suspends. This PR adds a new HostConfig method to check if `window.event === 'popstate'`, and `scheduleMicrotask` if a transition is scheduled in a `PopStateEvent`. ## How did you test this change? yarn test DiffTrain build for commit d121c67.
Summary
Browsers restore state like forms and scroll position right after the popstate event. To make sure the page work as expected on back or forward button, we need to flush transitions scheduled in a popstate synchronously, and only yields if it suspends.
This PR adds a new HostConfig method to check if
window.event === 'popstate'
, andscheduleMicrotask
if a transition is scheduled in aPopStateEvent
.How did you test this change?
yarn test