Skip to content

Conversation

sebmarkbage
Copy link
Collaborator

Stacked on #34481.

We currently track the suspended state temporarily with a global which is safe as long as we always read it during a sync pass. However, we sometimes read it in closures and then we have to be carefully to pass the right one since it's possible another commit on a different root has started at that point. This avoids this footgun.

Another reason to do this is that I want to read it in startViewTransition which is in an async gap after which point it's no longer safe. So I have to pass that through the commitRoot bound function.

@sebmarkbage sebmarkbage requested a review from gnoff September 14, 2025 17:13
@meta-cla meta-cla bot added the CLA Signed label Sep 14, 2025
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Sep 14, 2025
@react-sizebot
Copy link

react-sizebot commented Sep 14, 2025

Comparing: ae22247...48d796e

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.68 kB 6.68 kB +0.05% 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js +0.08% 533.85 kB 534.29 kB +0.05% 94.27 kB 94.32 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB +0.11% 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js +0.08% 661.64 kB 662.18 kB +0.05% 116.62 kB 116.68 kB
facebook-www/ReactDOM-prod.classic.js +0.05% 685.80 kB 686.13 kB +0.01% 120.69 kB 120.71 kB
facebook-www/ReactDOM-prod.modern.js +0.05% 676.23 kB 676.56 kB +0.01% 119.04 kB 119.05 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.production.js +0.26% 482.57 kB 483.81 kB +0.16% 76.77 kB 76.89 kB
oss-experimental/react-reconciler/cjs/react-reconciler.profiling.js +0.20% 545.58 kB 546.70 kB +0.15% 85.44 kB 85.56 kB
facebook-www/ReactReconciler-prod.modern.js +0.20% 500.99 kB 502.00 kB +0.11% 79.70 kB 79.79 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-persistent.development.js = 43.14 kB 42.73 kB = 7.78 kB 7.73 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-persistent.development.js = 43.13 kB 42.73 kB = 7.77 kB 7.73 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-persistent.development.js = 43.11 kB 42.70 kB = 7.75 kB 7.70 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer.development.js = 43.00 kB 42.59 kB = 7.76 kB 7.72 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer.development.js = 42.99 kB 42.59 kB = 7.76 kB 7.71 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer.development.js = 42.97 kB 42.56 kB = 7.73 kB 7.68 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-persistent.production.js = 38.81 kB 38.42 kB = 7.17 kB 7.13 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-persistent.production.js = 38.80 kB 38.41 kB = 7.17 kB 7.13 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-persistent.production.js = 38.78 kB 38.39 kB = 7.14 kB 7.10 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer.production.js = 38.68 kB 38.29 kB = 7.15 kB 7.11 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer.production.js = 38.67 kB 38.28 kB = 7.15 kB 7.11 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer.production.js = 38.65 kB 38.26 kB = 7.12 kB 7.08 kB

Generated by 🚫 dangerJS against 48d796e

This is safer since some calls need this to be closed over anyway.

This will let us persist it longer like into the commit phase.
That way we can transfer state from the collection of suspense commit info
into the view transition start.
@sebmarkbage sebmarkbage merged commit 5d49b2b into facebook:main Sep 15, 2025
178 of 180 checks passed
github-actions bot pushed a commit that referenced this pull request Sep 15, 2025
Stacked on #34481.

We currently track the suspended state temporarily with a global which
is safe as long as we always read it during a sync pass. However, we
sometimes read it in closures and then we have to be carefully to pass
the right one since it's possible another commit on a different root has
started at that point. This avoids this footgun.

Another reason to do this is that I want to read it in
`startViewTransition` which is in an async gap after which point it's no
longer safe. So I have to pass that through the `commitRoot` bound
function.

DiffTrain build for [5d49b2b](5d49b2b)
Copy link
Collaborator

@gnoff gnoff left a comment

Choose a reason for hiding this comment

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

Approved

sebmarkbage added a commit that referenced this pull request Sep 15, 2025
…nimation (#34500)

Stacked on #34486.

If we gave up on loading suspensey images for blocking the commit (e.g.
due to #34481), we can still block the view transition from committing
to allow an animation to include the image from the start.

At this point we have more information about the layout so we can
include only the images that are within viewport in the calculation
which may end up with a different answer.

This only applies when we attempt to run an animation (e.g. something
mutated inside a `<ViewTransition>` in a Transition). We could attempt a
`startViewTransition` if we gave up on the suspensey images just so that
we could block it even if no animation would be running.

However, this point the screen is frozen and you can no longer have sync
updates interrupt so ideally we would have already blocked the commit
from happening in the first place.

The reason to have two points where we block is that ideally we leave
the UI responsive while blocking, which blocking the commit does. In the
simple case of all images or a single image being within the viewport,
that's favorable. By combining the techniques we only end up freezing
the screen in the special case that we had a lot of images added outside
the viewport and started an animation with some image inside the
viewport (which presumably is about to finish anyway).
github-actions bot pushed a commit that referenced this pull request Sep 15, 2025
…nimation (#34500)

Stacked on #34486.

If we gave up on loading suspensey images for blocking the commit (e.g.
due to #34481), we can still block the view transition from committing
to allow an animation to include the image from the start.

At this point we have more information about the layout so we can
include only the images that are within viewport in the calculation
which may end up with a different answer.

This only applies when we attempt to run an animation (e.g. something
mutated inside a `<ViewTransition>` in a Transition). We could attempt a
`startViewTransition` if we gave up on the suspensey images just so that
we could block it even if no animation would be running.

However, this point the screen is frozen and you can no longer have sync
updates interrupt so ideally we would have already blocked the commit
from happening in the first place.

The reason to have two points where we block is that ideally we leave
the UI responsive while blocking, which blocking the commit does. In the
simple case of all images or a single image being within the viewport,
that's favorable. By combining the techniques we only end up freezing
the screen in the special case that we had a lot of images added outside
the viewport and started an animation with some image inside the
viewport (which presumably is about to finish anyway).

DiffTrain build for [348a4e2](348a4e2)
github-actions bot pushed a commit that referenced this pull request Sep 15, 2025
…nimation (#34500)

Stacked on #34486.

If we gave up on loading suspensey images for blocking the commit (e.g.
due to #34481), we can still block the view transition from committing
to allow an animation to include the image from the start.

At this point we have more information about the layout so we can
include only the images that are within viewport in the calculation
which may end up with a different answer.

This only applies when we attempt to run an animation (e.g. something
mutated inside a `<ViewTransition>` in a Transition). We could attempt a
`startViewTransition` if we gave up on the suspensey images just so that
we could block it even if no animation would be running.

However, this point the screen is frozen and you can no longer have sync
updates interrupt so ideally we would have already blocked the commit
from happening in the first place.

The reason to have two points where we block is that ideally we leave
the UI responsive while blocking, which blocking the commit does. In the
simple case of all images or a single image being within the viewport,
that's favorable. By combining the techniques we only end up freezing
the screen in the special case that we had a lot of images added outside
the viewport and started an animation with some image inside the
viewport (which presumably is about to finish anyway).

DiffTrain build for [348a4e2](348a4e2)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Sep 20, 2025
…nimation (facebook#34500)

Stacked on facebook#34486.

If we gave up on loading suspensey images for blocking the commit (e.g.
due to facebook#34481), we can still block the view transition from committing
to allow an animation to include the image from the start.

At this point we have more information about the layout so we can
include only the images that are within viewport in the calculation
which may end up with a different answer.

This only applies when we attempt to run an animation (e.g. something
mutated inside a `<ViewTransition>` in a Transition). We could attempt a
`startViewTransition` if we gave up on the suspensey images just so that
we could block it even if no animation would be running.

However, this point the screen is frozen and you can no longer have sync
updates interrupt so ideally we would have already blocked the commit
from happening in the first place.

The reason to have two points where we block is that ideally we leave
the UI responsive while blocking, which blocking the commit does. In the
simple case of all images or a single image being within the viewport,
that's favorable. By combining the techniques we only end up freezing
the screen in the special case that we had a lot of images added outside
the viewport and started an animation with some image inside the
viewport (which presumably is about to finish anyway).

DiffTrain build for [348a4e2](facebook@348a4e2)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Sep 20, 2025
…nimation (facebook#34500)

Stacked on facebook#34486.

If we gave up on loading suspensey images for blocking the commit (e.g.
due to facebook#34481), we can still block the view transition from committing
to allow an animation to include the image from the start.

At this point we have more information about the layout so we can
include only the images that are within viewport in the calculation
which may end up with a different answer.

This only applies when we attempt to run an animation (e.g. something
mutated inside a `<ViewTransition>` in a Transition). We could attempt a
`startViewTransition` if we gave up on the suspensey images just so that
we could block it even if no animation would be running.

However, this point the screen is frozen and you can no longer have sync
updates interrupt so ideally we would have already blocked the commit
from happening in the first place.

The reason to have two points where we block is that ideally we leave
the UI responsive while blocking, which blocking the commit does. In the
simple case of all images or a single image being within the viewport,
that's favorable. By combining the techniques we only end up freezing
the screen in the special case that we had a lot of images added outside
the viewport and started an animation with some image inside the
viewport (which presumably is about to finish anyway).

DiffTrain build for [348a4e2](facebook@348a4e2)
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