Repository navigation
Conversation
Tests that a hidden subtree isn't cloned on every commit that lays out its parent, through React commits and setNativeProps, and that hidden screens lay out the same as never-hidden ones once shown again. The second test depends on react/yoga#2055 and fails until that change is synced into the vendored copy of Yoga. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shubh73
force-pushed
the
skip-recloning-zeroed-display-none
branch
from
October 31, 2026 02:11
d0c6c7d to
ec757d9
Compare
display: none subtrees on every layout passdisplay: none subtrees not being cloned again
shubh73
marked this pull request as draft
October 31, 2026 02:11
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
react/yoga#2055 stops
zeroOutLayoutRecursivelyfrom cloningdisplay: nonesubtrees that are already zeroed out. Without it, every commit that lays out the parent of a hidden view clones every node under it (yogaNodeCloneCallbackConnector→cloneChildInPlace), andYogaLayoutableShadowNode::layout()never settles those clones because it doesn't descend intodisplay: none. React commits re-run layout along the path to a change, so even a colour change pays it. On Android the differ then walks the freshly cloned subtrees too, sinceuseTraitHiddenOnAndroidis off by default.The cost grows with every screen kept mounted with
display: none:<Activity mode="hidden">ActivityView)detachInactiveScreens={false}(Screen.tsx) orfreezeOnBlur(react-freeze)expo-router/ui) (TabSlot.tsx)#59113 fixed the related case where those subtrees dirtied their ancestors.
The Yoga change reaches React Native through the Yoga sync. This PR adds a Fantom test for it, so it should land after the sync. It's a draft until then.
On an OPPO CPH2667 (Android 16, RNTester release build), with N hidden screens of about 500 nodes each, the change brings the extra time per update to the visible screen at N = 10 from +13.0 ms to +5.9 ms. The details are in react/yoga#2055. Most of what remains is the differ walk that
useTraitHiddenOnAndroidskips: with the flag on as well, it's +1.8 ms.Changelog:
[INTERNAL] [ADDED] - Fantom test for
display: nonesubtrees not being cloned on every commitTest Plan:
View-hiddenSubtrees-itest.jsadds two tests:lays out a screen shown again after updates while it was hidden: hidden screens are updated while hidden and then shown, and must lay out the same as screens that were never hidden. This covers resizes around them, content added and removed while hidden,display: contents, nesteddisplay: noneand non-absolute screens. It passes with and without Don't clone zeroed outdisplay: nonesubtrees on every layout pass yoga#2055.does not clone a hidden subtree when its parent is laid out again: a hidden descendant's ShadowNode revision must stay the same across React commits and asetNativePropscommit that lay out its parent. It fails onmain("Expected 1 but received 3") and passes with Don't clone zeroed outdisplay: nonesubtrees on every layout pass yoga#2055 applied to the vendored copy.With react/yoga#2055 applied to the vendored copy and a Debug tester (
react_native_asserton), the rest of the Fantom suite doesn't change.🤖 Generated with Claude Code