diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 82b05cec891ca0..b084ccbb43d1b7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -157,4 +157,7 @@ public class ReactFeatureFlags { /** Only swap left and right on Android in RTL scripts. */ public static boolean doNotSwapLeftAndRightOnAndroidInLTR = false; + + /** Clean yoga node when does not change. */ + public static boolean enableCleanParagraphYogaNode = false; } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp index 65d6db392f8500..ea4cf210f4bb19 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp @@ -433,6 +433,8 @@ void Binding::installFabricUIManager( CoreFeatures::enableMapBuffer = getFeatureFlagValue("useMapBufferProps"); CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR = getFeatureFlagValue("doNotSwapLeftAndRightOnAndroidInLTR"); + CoreFeatures::enableCleanParagraphYogaNode = + getFeatureFlagValue("enableCleanParagraphYogaNode"); // RemoveDelete mega-op ShadowViewMutation::PlatformSupportsRemoveDeleteTreeInstruction = diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp index 17cb7dd34ad1c1..274b9b4b36d548 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "ParagraphState.h" @@ -25,6 +26,20 @@ using Content = ParagraphShadowNode::Content; char const ParagraphComponentName[] = "Paragraph"; +ParagraphShadowNode::ParagraphShadowNode( + ShadowNode const &sourceShadowNode, + ShadowNodeFragment const &fragment) + : ConcreteViewShadowNode(sourceShadowNode, fragment) { + if (CoreFeatures::enableCleanParagraphYogaNode) { + if (!fragment.children && !fragment.props) { + // This ParagraphShadowNode was cloned but did not change + // in a way that affects its layout. Let's mark it clean + // to stop Yoga from traversing it. + cleanLayout(); + } + } +} + Content const &ParagraphShadowNode::getContent( LayoutContext const &layoutContext) const { if (content_.has_value()) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.h index b44e8f416dc675..40f399b91fd6da 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.h @@ -34,6 +34,10 @@ class ParagraphShadowNode final : public ConcreteViewShadowNode< public: using ConcreteViewShadowNode::ConcreteViewShadowNode; + ParagraphShadowNode( + ShadowNode const &sourceShadowNode, + ShadowNodeFragment const &fragment); + static ShadowNodeTraits BaseTraits() { auto traits = ConcreteViewShadowNode::BaseTraits(); traits.set(ShadowNodeTraits::Trait::LeafYogaNode); diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index 2c3ce14e5ba61a..e44b019050176b 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -18,5 +18,6 @@ bool CoreFeatures::cancelImageDownloadsOnRecycle = false; bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; bool CoreFeatures::enableMountHooks = false; bool CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR = false; +bool CoreFeatures::enableCleanParagraphYogaNode = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 8070cb4006f909..2d693ffc68b0fc 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -53,6 +53,9 @@ class CoreFeatures { // Only swap left and right on Android in RTL scripts. static bool doNotSwapLeftAndRightOnAndroidInLTR; + + // Clean yoga node when does not change. + static bool enableCleanParagraphYogaNode; }; } // namespace facebook::react