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