Skip to content
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

Support nesting of React.startTransition and ReactDOM.flushSync #21136

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Mar 30, 2021

Currently we track event priorities in two different places:

  • For transitions, we use the ReactCurrentBatchConfig object, which lives in the secret internals object of the isomorphic package. This is how the hook-less startTransition works.
  • For other types of events, we use a module-level variable in ReactEventPriorities, which is owned by the renderer.

The problem with this approach is if both priorities are set, we don't know which one takes precedence. For example, what happens if wrap an update in both ReactDOM.flushSync and React.startTransition?

The desired behavior is that we use the priority of whichever wrapper is closer on the stack. So if flushSync is called inside of startTransition, then we should use sync priority; if it's the other way around, we should use transition priority.

To implement this, I updated the ReactEventPriorities module to track priority on the ReactCurrentBatchConfig object instead of in a module- level variable. Now when multiple event wrappers are nested, the innermost wrapper wins.

Currently we track event priorities in two different places:

- For transitions, we use the ReactCurrentBatchConfig object, which
  lives in the secret internals object of the isomorphic package. This
  is how the hook-less `startTransition` works.
- For other types of events, we use a module-level variable in
  ReactEventPriorities, which is owned by the renderer.

The problem with this approach is if both priorities are set, we don't
know which one takes precedence. For example, what happens if wrap an
update in both `ReactDOM.flushSync` and `React.startTransition`?

The desired behavior is that we use the priority of whichever wrapper
is closer on the stack. So if `flushSync` is called inside of
`startTransition`, then we should use sync priority; if it's the other
way around, we should use transition priority.

To implement this, I updated the ReactEventPriorities module to track
priority on the ReactCurrentBatchConfig object instead of in a module-
level variable. Now when multiple event wrappers are nested, the inner-
most wrapper wins.
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Mar 30, 2021
@sizebot
Copy link

sizebot commented Mar 30, 2021

Comparing: 0853aab...16a8eca

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js +0.16% 122.27 kB 122.47 kB +0.10% 39.24 kB 39.28 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.15% 128.78 kB 128.98 kB +0.08% 41.32 kB 41.35 kB
facebook-www/ReactDOM-prod.classic.js +0.11% 404.48 kB 404.92 kB +0.07% 75.20 kB 75.25 kB
facebook-www/ReactDOM-prod.modern.js +0.04% 392.73 kB 392.89 kB +0.05% 73.31 kB 73.35 kB
facebook-www/ReactDOMForked-prod.classic.js +0.11% 404.48 kB 404.92 kB +0.07% 75.20 kB 75.25 kB
oss-experimental/react-reconciler/cjs/react-reconciler-constants.development.js +25.83% 1.06 kB 1.33 kB +32.96% 0.45 kB 0.59 kB
oss-stable/react-reconciler/cjs/react-reconciler-constants.development.js +25.83% 1.06 kB 1.33 kB +32.96% 0.45 kB 0.59 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-reconciler/cjs/react-reconciler-constants.development.js +25.83% 1.06 kB 1.33 kB +32.96% 0.45 kB 0.59 kB
oss-stable/react-reconciler/cjs/react-reconciler-constants.development.js +25.83% 1.06 kB 1.33 kB +32.96% 0.45 kB 0.59 kB
oss-experimental/react/cjs/react.development.js +0.90% 73.71 kB 74.37 kB +1.50% 19.77 kB 20.07 kB
facebook-react-native/react/cjs/React-dev.js +0.75% 88.61 kB 89.27 kB +1.35% 21.28 kB 21.57 kB
facebook-www/React-dev.modern.js +0.69% 97.34 kB 98.01 kB +1.36% 23.75 kB 24.07 kB
facebook-www/React-dev.classic.js +0.68% 98.36 kB 99.03 kB +1.21% 23.98 kB 24.27 kB
oss-experimental/react/umd/react.development.js +0.65% 106.17 kB 106.86 kB +1.07% 26.28 kB 26.56 kB
oss-stable/react-test-renderer/umd/react-test-renderer.production.min.js +0.27% 79.38 kB 79.59 kB +0.07% 24.94 kB 24.96 kB
oss-stable/react-test-renderer/cjs/react-test-renderer.production.min.js +0.26% 79.22 kB 79.43 kB +0.05% 24.69 kB 24.70 kB
oss-experimental/react-test-renderer/umd/react-test-renderer.production.min.js +0.26% 81.74 kB 81.95 kB +0.08% 25.75 kB 25.77 kB
oss-experimental/react-test-renderer/cjs/react-test-renderer.production.min.js +0.25% 81.59 kB 81.79 kB +0.04% 25.44 kB 25.45 kB
oss-stable/react-art/cjs/react-art.production.min.js +0.23% 76.39 kB 76.57 kB +0.08% 23.80 kB 23.82 kB
oss-experimental/react-art/cjs/react-art.production.min.js +0.21% 81.24 kB 81.41 kB +0.01% 25.27 kB 25.28 kB

Generated by 🚫 dangerJS against 16a8eca

@acdlite acdlite force-pushed the support-nesting-starttransition-flushsync branch 2 times, most recently from 6d7dc04 to f2a4e8c Compare March 30, 2021 03:57
@acdlite acdlite force-pushed the support-nesting-starttransition-flushsync branch 3 times, most recently from 9d2d689 to 16a8eca Compare March 31, 2021 04:02
@acdlite acdlite changed the title RFC: Support nesting of React.startTransition and ReactDOM.flushSync Support nesting of React.startTransition and ReactDOM.flushSync Mar 31, 2021
// boundary: importing from a shared module would give a false sense of
// DRYness, because it's theoretically possible for for the renderer and
// the isomorphic package to be out of sync. We don't fully support that, but we
// should try (within reason) to be resilient.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, copying over gives a false sense of safety since if the renderer and isomorphic are out of sync, this could also be wrong.

@acdlite
Copy link
Collaborator Author

acdlite commented Mar 31, 2021

Closed in favor of #21149

@acdlite acdlite closed this Mar 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants