You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The C++ native animated backend (cxxNativeAnimatedEnabled) prevents the useNativeDriver first-frame flash by having AnimatedMountingOverrideDelegate re-merge a view's live animated props (getManagedProps) onto mount Update mutations, so a stale JS re-render can't reach the screen. There is a residual at connect time: connectAnimatedNodeToView registers the view (the override starts overriding it) but never runs the props node, so getManagedProps() returns an empty object until the next animation frame. If a Fabric mount transaction is pulled in that window the override has nothing to merge and the un-driven default value flashes for one frame, most visibly when a brand-new view is connected to an already mid-flight shared Animated.Value.
This seeds the props node with node->update() at the end of connectAnimatedNodeToView so getManagedProps() is live the instant the view becomes managed. No manager mutex is held at that point and update() takes only the node-local props mutex, so it is lock-safe; it is idempotent with the per-frame update and adds no extra Fabric commit because it only stages. It closes the connect-while-Update-in-flight case and mitigates the brand-new-view (Insert) first-paint case; the override only rewrites Update/Delete mutations today, so fully closing Insert is a follow-up. It also adds the missing unit coverage for the getManagedProps / hasManagedProps seam the override depends on.
Changelog:
[INTERNAL] [FIXED] - Seed managed props when a view connects to the native animated backend so they are live before the first frame, shrinking the useNativeDriver mount flash
Test Plan:
Adds ManagedPropsMountingOverrideTests.cpp to the ReactCommon animated unit tests. getManagedPropsReflectsLiveValueAcrossFrames, getManagedPropsNullForUnconnectedView, hasManagedPropsTracksConnectAndDisconnect and getManagedPropsIsolatedPerView pin the seam and pass regardless of the change. getManagedPropsLiveImmediatelyOnConnect and getManagedPropsLiveOnConnectWhileValueMidFlight are the regression cases: they fail without the seed (empty props at connect) and pass with it. Run via the animated C++ unit test target. On-device verification (iOS and Android with cxxNativeAnimatedEnabled on, frame-stepped capture of a popover/menu open) is still recommended for the user-visible flash.
meta-claBot
added
the
CLA Signed
This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
label
Jun 30, 2026
@GrahamCampbell thanks for the PR, do you have a playground repro for this issue? In fact Props node->update() will trigger a commit to the native view, so I'm a bit concerned of the side effects of doing this
Thanks for the review. update only stages props (map writes). The actual view push is in commitProps, which it never reaches. connectAnimatedNodeToView already dirties the node, so the commit happens that frame regardless. To make that structural, I pushed a follow-up that seeds via a collect-only collectProps with no schedulePropsCommit.
@zeyap has imported this pull request. If you are a Meta employee, you can view this in D110323404.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CLA SignedThis label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.Shared with MetaApplied via automation to indicate that an Issue or Pull Request has been shared with the team.
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
The C++ native animated backend (
cxxNativeAnimatedEnabled) prevents theuseNativeDriverfirst-frame flash by havingAnimatedMountingOverrideDelegatere-merge a view's live animated props (getManagedProps) onto mountUpdatemutations, so a stale JS re-render can't reach the screen. There is a residual at connect time:connectAnimatedNodeToViewregisters the view (the override starts overriding it) but never runs the props node, sogetManagedProps()returns an empty object until the next animation frame. If a Fabric mount transaction is pulled in that window the override has nothing to merge and the un-driven default value flashes for one frame, most visibly when a brand-new view is connected to an already mid-flight sharedAnimated.Value.This seeds the props node with
node->update()at the end ofconnectAnimatedNodeToViewsogetManagedProps()is live the instant the view becomes managed. No manager mutex is held at that point andupdate()takes only the node-local props mutex, so it is lock-safe; it is idempotent with the per-frame update and adds no extra Fabric commit because it only stages. It closes the connect-while-Update-in-flight case and mitigates the brand-new-view (Insert) first-paint case; the override only rewritesUpdate/Deletemutations today, so fully closingInsertis a follow-up. It also adds the missing unit coverage for thegetManagedProps/hasManagedPropsseam the override depends on.Changelog:
[INTERNAL] [FIXED] - Seed managed props when a view connects to the native animated backend so they are live before the first frame, shrinking the useNativeDriver mount flash
Test Plan:
Adds
ManagedPropsMountingOverrideTests.cppto the ReactCommon animated unit tests.getManagedPropsReflectsLiveValueAcrossFrames,getManagedPropsNullForUnconnectedView,hasManagedPropsTracksConnectAndDisconnectandgetManagedPropsIsolatedPerViewpin the seam and pass regardless of the change.getManagedPropsLiveImmediatelyOnConnectandgetManagedPropsLiveOnConnectWhileValueMidFlightare the regression cases: they fail without the seed (empty props at connect) and pass with it. Run via the animated C++ unit test target. On-device verification (iOS and Android withcxxNativeAnimatedEnabledon, frame-stepped capture of a popover/menu open) is still recommended for the user-visible flash.