⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

@sebmarkbage
Copy link
Collaborator

Stacked on #35487.

This is slightly different because the first suspended commit is on blockers that prevent us from committing which still needs to be resolved first.

If a gesture lane has to be rerendered while the gesture is happening then it reenters this state with a new tree. (Currently this doesn't happen for a ping I think which is not really how it usually works but better in this case.)

@sebmarkbage sebmarkbage requested a review from acdlite January 14, 2026 20:18
@meta-cla meta-cla bot added the CLA Signed label Jan 14, 2026
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Jan 14, 2026
@react-sizebot
Copy link

react-sizebot commented Jan 14, 2026

Comparing: 35a81ce...3a51d91

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.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 608.20 kB 608.20 kB = 107.66 kB 107.66 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB = 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js +0.14% 669.74 kB 670.66 kB +0.07% 118.00 kB 118.08 kB
facebook-www/ReactDOM-prod.classic.js = 693.57 kB 693.57 kB = 122.05 kB 122.05 kB
facebook-www/ReactDOM-prod.modern.js = 683.95 kB 683.95 kB = 120.44 kB 120.44 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-art/cjs/react-art.production.js +0.46% 356.88 kB 358.53 kB +0.38% 60.22 kB 60.45 kB
oss-experimental/react-reconciler/cjs/react-reconciler.profiling.js +0.29% 566.12 kB 567.78 kB +0.29% 88.17 kB 88.42 kB
oss-experimental/react-art/cjs/react-art.development.js +0.26% 731.96 kB 733.87 kB +0.27% 115.16 kB 115.46 kB
oss-experimental/react-reconciler/cjs/react-reconciler.development.js +0.23% 860.38 kB 862.37 kB +0.22% 134.01 kB 134.30 kB
oss-experimental/react-dom/cjs/react-dom-profiling.profiling.js +0.21% 748.39 kB 749.95 kB +0.22% 129.36 kB 129.64 kB

Generated by 🚫 dangerJS against 3a51d91

startTransition(action);
}
// We cancel the gesture before invoking side-effects to allow the gesture lane to fully commit
// before scheduling new updates.
Copy link
Collaborator Author

@sebmarkbage sebmarkbage Jan 14, 2026

Choose a reason for hiding this comment

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

This might actually be wrong because it wouldn't know what to entangle with until later. Nevermind this works because we entangle all transitions in the same event.

@sebmarkbage
Copy link
Collaborator Author

I also pushed some commits related to performance track logging of these new types of phases and gaps.

@sebmarkbage sebmarkbage changed the title Optimize gesture by allowing the original work in progress tree to be a suspended comimt Optimize gesture by allowing the original work in progress tree to be a suspended commit Jan 15, 2026
sebmarkbage added a commit that referenced this pull request Jan 16, 2026
…35486)

Stacked on #35485.

Before this PR, the `startGestureTransition` API would itself never
commit its state. After the gesture releases it stops the animation in
the next commit which just leaves the DOM tree in the original state. If
there's an actual state change from the Action then that's committed as
the new DOM tree. To avoid animating from the original state to the new
state again, this is DOM without an animation. However, this means that
you can't have the actual action committing be in a slightly different
state and animate between the final gesture state and into the new
action.

Instead, we now actually keep the render tree around and commit it in
the end. Basically we assume that if the Timeline was closer to the end
then visually you're already there and we can commit into that state.
Most of the time this will be at the actual end state when you release
but if you have something else cancelling the gesture (e.g.
`touchcancel`) it can still commit this state even though your gesture
recognizer might not consider this an Action. I think this is ok and
keeps it simple.

When the gesture lane commits, it'll leave a Transition behind as work
from the revert lanes on the Optimistic updates. This means that if you
don't do anything in the Action this will cause another commit right
after which reverts. This revert can animate the snap back.

There's a few fixes needed in follow up PRs:

- Fixed in #35487. ~To support unentangled Transitions we need to
explicitly entangle the revert lane with the Action to avoid committing
a revert followed by a forward instead of committing the forward
entangled with the revert. This just works now since everything is
entangled but won't work with #35392.~
- Fixed in #35510. ~This currently rerenders the gesture lane once
before committing if it was already completed but blocked. We should be
able to commit the already completed tree as is.~
This is equivalent to the "Commit" phase in the regular phases but it's
creating a "ghost" DOM tree that's a partial clone of the old one that's
immediately deleted.
This ensures that we log the end state of the Animating track which
otherwise is ignored inside a commit phase.
@sebmarkbage sebmarkbage force-pushed the commitoriginalgesture branch from 29fd03b to 3a51d91 Compare January 16, 2026 01:45
github-actions bot pushed a commit that referenced this pull request Jan 16, 2026
…35486)

Stacked on #35485.

Before this PR, the `startGestureTransition` API would itself never
commit its state. After the gesture releases it stops the animation in
the next commit which just leaves the DOM tree in the original state. If
there's an actual state change from the Action then that's committed as
the new DOM tree. To avoid animating from the original state to the new
state again, this is DOM without an animation. However, this means that
you can't have the actual action committing be in a slightly different
state and animate between the final gesture state and into the new
action.

Instead, we now actually keep the render tree around and commit it in
the end. Basically we assume that if the Timeline was closer to the end
then visually you're already there and we can commit into that state.
Most of the time this will be at the actual end state when you release
but if you have something else cancelling the gesture (e.g.
`touchcancel`) it can still commit this state even though your gesture
recognizer might not consider this an Action. I think this is ok and
keeps it simple.

When the gesture lane commits, it'll leave a Transition behind as work
from the revert lanes on the Optimistic updates. This means that if you
don't do anything in the Action this will cause another commit right
after which reverts. This revert can animate the snap back.

There's a few fixes needed in follow up PRs:

- Fixed in #35487. ~To support unentangled Transitions we need to
explicitly entangle the revert lane with the Action to avoid committing
a revert followed by a forward instead of committing the forward
entangled with the revert. This just works now since everything is
entangled but won't work with #35392.~
- Fixed in #35510. ~This currently rerenders the gesture lane once
before committing if it was already completed but blocked. We should be
able to commit the already completed tree as is.~

DiffTrain build for [4028aaa](4028aaa)
github-actions bot pushed a commit that referenced this pull request Jan 16, 2026
…35486)

Stacked on #35485.

Before this PR, the `startGestureTransition` API would itself never
commit its state. After the gesture releases it stops the animation in
the next commit which just leaves the DOM tree in the original state. If
there's an actual state change from the Action then that's committed as
the new DOM tree. To avoid animating from the original state to the new
state again, this is DOM without an animation. However, this means that
you can't have the actual action committing be in a slightly different
state and animate between the final gesture state and into the new
action.

Instead, we now actually keep the render tree around and commit it in
the end. Basically we assume that if the Timeline was closer to the end
then visually you're already there and we can commit into that state.
Most of the time this will be at the actual end state when you release
but if you have something else cancelling the gesture (e.g.
`touchcancel`) it can still commit this state even though your gesture
recognizer might not consider this an Action. I think this is ok and
keeps it simple.

When the gesture lane commits, it'll leave a Transition behind as work
from the revert lanes on the Optimistic updates. This means that if you
don't do anything in the Action this will cause another commit right
after which reverts. This revert can animate the snap back.

There's a few fixes needed in follow up PRs:

- Fixed in #35487. ~To support unentangled Transitions we need to
explicitly entangle the revert lane with the Action to avoid committing
a revert followed by a forward instead of committing the forward
entangled with the revert. This just works now since everything is
entangled but won't work with #35392.~
- Fixed in #35510. ~This currently rerenders the gesture lane once
before committing if it was already completed but blocked. We should be
able to commit the already completed tree as is.~

DiffTrain build for [4028aaa](4028aaa)
@sebmarkbage sebmarkbage merged commit 4cf9063 into facebook:main Jan 16, 2026
233 of 234 checks passed
github-actions bot pushed a commit that referenced this pull request Jan 16, 2026
… a suspended commit (#35510)

Stacked on #35487.

This is slightly different because the first suspended commit is on
blockers that prevent us from committing which still needs to be
resolved first.

If a gesture lane has to be rerendered while the gesture is happening
then it reenters this state with a new tree. (Currently this doesn't
happen for a ping I think which is not really how it usually works but
better in this case.)

DiffTrain build for [4cf9063](4cf9063)
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.

3 participants