Add separate flags for recycling View, Text components (#49211)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49211

Add more control over view recycling behavior by splitting out each component that currently supports it.

Changelog:[Android][Added] Feature flags for recycling View, Text components separately

Reviewed By: sammy-SC, mdvacca

Differential Revision: D69190841

fbshipit-source-id: 6d85fee7103bf928e4f5bf6946bab3ff4cae4053
This commit is contained in:
Thomas Nardone
2025-02-05 18:36:06 -08:00
committed by Facebook GitHub Bot
parent fb8a6a5bb0
commit ca5ce205f7
22 changed files with 279 additions and 39 deletions
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<5d3aa805cfedaf97ef3e6229046dc288>>
* @generated SignedSource<<d7e150b5b7f7b62f347bc417f542f2ba>>
*/
/**
@@ -172,6 +172,18 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableViewRecycling(): Boolean = accessor.enableViewRecycling()
/**
* Enables View Recycling for <Text> via ReactTextView/ReactTextViewManager.
*/
@JvmStatic
public fun enableViewRecyclingForText(): Boolean = accessor.enableViewRecyclingForText()
/**
* Enables View Recycling for <View> via ReactViewGroup/ReactViewManager.
*/
@JvmStatic
public fun enableViewRecyclingForView(): Boolean = accessor.enableViewRecyclingForView()
/**
* When enabled, rawProps in Props will not include Yoga specific props.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<001f61b20e3bacb67e4145a257cb92b1>>
* @generated SignedSource<<ae7503526759f8b9f1ef56207ee1cab5>>
*/
/**
@@ -44,6 +44,8 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForTextCache: Boolean? = null
private var enableViewRecyclingForViewCache: Boolean? = null
private var excludeYogaFromRawPropsCache: Boolean? = null
private var fixDifferentiatorEmittingUpdatesWithWrongParentTagCache: Boolean? = null
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
@@ -278,6 +280,24 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableViewRecyclingForText(): Boolean {
var cached = enableViewRecyclingForTextCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableViewRecyclingForText()
enableViewRecyclingForTextCache = cached
}
return cached
}
override fun enableViewRecyclingForView(): Boolean {
var cached = enableViewRecyclingForViewCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableViewRecyclingForView()
enableViewRecyclingForViewCache = cached
}
return cached
}
override fun excludeYogaFromRawProps(): Boolean {
var cached = excludeYogaFromRawPropsCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<745b574df700a813a49fed3c88aada66>>
* @generated SignedSource<<5292a5f705fc3587ee9d81cc83a79c05>>
*/
/**
@@ -76,6 +76,10 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableViewRecycling(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecyclingForText(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecyclingForView(): Boolean
@DoNotStrip @JvmStatic public external fun excludeYogaFromRawProps(): Boolean
@DoNotStrip @JvmStatic public external fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<86207e36abfecc310dbd28b8d61c5fbf>>
* @generated SignedSource<<d904f548576348ea7a6eb58fa306faea>>
*/
/**
@@ -71,6 +71,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableViewRecycling(): Boolean = false
override fun enableViewRecyclingForText(): Boolean = true
override fun enableViewRecyclingForView(): Boolean = true
override fun excludeYogaFromRawProps(): Boolean = false
override fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean = true
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c2ee44bcc04c2ab7fdb14c66980c7d73>>
* @generated SignedSource<<f2440756231f770d7240112ed2a460d8>>
*/
/**
@@ -48,6 +48,8 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForTextCache: Boolean? = null
private var enableViewRecyclingForViewCache: Boolean? = null
private var excludeYogaFromRawPropsCache: Boolean? = null
private var fixDifferentiatorEmittingUpdatesWithWrongParentTagCache: Boolean? = null
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
@@ -306,6 +308,26 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun enableViewRecyclingForText(): Boolean {
var cached = enableViewRecyclingForTextCache
if (cached == null) {
cached = currentProvider.enableViewRecyclingForText()
accessedFeatureFlags.add("enableViewRecyclingForText")
enableViewRecyclingForTextCache = cached
}
return cached
}
override fun enableViewRecyclingForView(): Boolean {
var cached = enableViewRecyclingForViewCache
if (cached == null) {
cached = currentProvider.enableViewRecyclingForView()
accessedFeatureFlags.add("enableViewRecyclingForView")
enableViewRecyclingForViewCache = cached
}
return cached
}
override fun excludeYogaFromRawProps(): Boolean {
var cached = excludeYogaFromRawPropsCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<e592fe3140fb310638240a84bd3f3e8f>>
* @generated SignedSource<<3bb3618781161c0b6beaffcfabf0288c>>
*/
/**
@@ -71,6 +71,10 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableViewRecycling(): Boolean
@DoNotStrip public fun enableViewRecyclingForText(): Boolean
@DoNotStrip public fun enableViewRecyclingForView(): Boolean
@DoNotStrip public fun excludeYogaFromRawProps(): Boolean
@DoNotStrip public fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean
@@ -18,6 +18,7 @@ import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.internal.SystraceSection;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.IViewManagerWithChildren;
import com.facebook.react.uimanager.ReactAccessibilityDelegate;
@@ -58,7 +59,9 @@ public class ReactTextViewManager
public ReactTextViewManager(@Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) {
mReactTextViewManagerCallback = reactTextViewManagerCallback;
setupViewRecycling();
if (ReactNativeFeatureFlags.enableViewRecyclingForText()) {
setupViewRecycling();
}
}
@Override
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType
import com.facebook.react.common.ReactConstants
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.BackgroundStyleApplicator
import com.facebook.react.uimanager.LengthPercentage
@@ -63,7 +64,9 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
}
init {
setupViewRecycling()
if (ReactNativeFeatureFlags.enableViewRecyclingForView()) {
setupViewRecycling()
}
}
override fun prepareToRecycleView(
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<89691e6748ef791ca022f1289304046d>>
* @generated SignedSource<<b04123b022b1f120895d027f8bc12a4e>>
*/
/**
@@ -183,6 +183,18 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool enableViewRecyclingForText() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableViewRecyclingForText");
return method(javaProvider_);
}
bool enableViewRecyclingForView() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableViewRecyclingForView");
return method(javaProvider_);
}
bool excludeYogaFromRawProps() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("excludeYogaFromRawProps");
@@ -409,6 +421,16 @@ bool JReactNativeFeatureFlagsCxxInterop::enableViewRecycling(
return ReactNativeFeatureFlags::enableViewRecycling();
}
bool JReactNativeFeatureFlagsCxxInterop::enableViewRecyclingForText(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableViewRecyclingForText();
}
bool JReactNativeFeatureFlagsCxxInterop::enableViewRecyclingForView(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableViewRecyclingForView();
}
bool JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::excludeYogaFromRawProps();
@@ -597,6 +619,12 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableViewRecycling",
JReactNativeFeatureFlagsCxxInterop::enableViewRecycling),
makeNativeMethod(
"enableViewRecyclingForText",
JReactNativeFeatureFlagsCxxInterop::enableViewRecyclingForText),
makeNativeMethod(
"enableViewRecyclingForView",
JReactNativeFeatureFlagsCxxInterop::enableViewRecyclingForView),
makeNativeMethod(
"excludeYogaFromRawProps",
JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps),
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<00ecf4fa0d9e7286d2ddb824970fb392>>
* @generated SignedSource<<141e3b288582658dac52d18b9f8fe273>>
*/
/**
@@ -102,6 +102,12 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableViewRecycling(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableViewRecyclingForText(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableViewRecyclingForView(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool excludeYogaFromRawProps(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<60a83d7d70d056023207212809b06014>>
* @generated SignedSource<<be4def74dca96760a42fe7da148a70ca>>
*/
/**
@@ -122,6 +122,14 @@ bool ReactNativeFeatureFlags::enableViewRecycling() {
return getAccessor().enableViewRecycling();
}
bool ReactNativeFeatureFlags::enableViewRecyclingForText() {
return getAccessor().enableViewRecyclingForText();
}
bool ReactNativeFeatureFlags::enableViewRecyclingForView() {
return getAccessor().enableViewRecyclingForView();
}
bool ReactNativeFeatureFlags::excludeYogaFromRawProps() {
return getAccessor().excludeYogaFromRawProps();
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<be7f92f605d34575519e7c8b2937ac5d>>
* @generated SignedSource<<ba638fd2dba475cb03191963f38692b4>>
*/
/**
@@ -159,6 +159,16 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableViewRecycling();
/**
* Enables View Recycling for <Text> via ReactTextView/ReactTextViewManager.
*/
RN_EXPORT static bool enableViewRecyclingForText();
/**
* Enables View Recycling for <View> via ReactViewGroup/ReactViewManager.
*/
RN_EXPORT static bool enableViewRecyclingForView();
/**
* When enabled, rawProps in Props will not include Yoga specific props.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<5e78f20d72608659ceed19d3d72eaba7>>
* @generated SignedSource<<3873ccb0828b6046d750f91b52011c76>>
*/
/**
@@ -461,6 +461,42 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() {
auto flagValue = enableViewRecyclingForText_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableViewRecyclingForText");
flagValue = currentProvider_->enableViewRecyclingForText();
enableViewRecyclingForText_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() {
auto flagValue = enableViewRecyclingForView_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "enableViewRecyclingForView");
flagValue = currentProvider_->enableViewRecyclingForView();
enableViewRecyclingForView_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() {
auto flagValue = excludeYogaFromRawProps_.load();
@@ -470,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "excludeYogaFromRawProps");
markFlagAsAccessed(26, "excludeYogaFromRawProps");
flagValue = currentProvider_->excludeYogaFromRawProps();
excludeYogaFromRawProps_ = flagValue;
@@ -488,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorEmittingUpdatesWithWrongP
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "fixDifferentiatorEmittingUpdatesWithWrongParentTag");
markFlagAsAccessed(27, "fixDifferentiatorEmittingUpdatesWithWrongParentTag");
flagValue = currentProvider_->fixDifferentiatorEmittingUpdatesWithWrongParentTag();
fixDifferentiatorEmittingUpdatesWithWrongParentTag_ = flagValue;
@@ -506,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(26, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
@@ -524,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(27, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
markFlagAsAccessed(29, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid();
fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue;
@@ -542,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(28, "fuseboxEnabledRelease");
markFlagAsAccessed(30, "fuseboxEnabledRelease");
flagValue = currentProvider_->fuseboxEnabledRelease();
fuseboxEnabledRelease_ = flagValue;
@@ -560,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(29, "fuseboxNetworkInspectionEnabled");
markFlagAsAccessed(31, "fuseboxNetworkInspectionEnabled");
flagValue = currentProvider_->fuseboxNetworkInspectionEnabled();
fuseboxNetworkInspectionEnabled_ = flagValue;
@@ -578,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(30, "lazyAnimationCallbacks");
markFlagAsAccessed(32, "lazyAnimationCallbacks");
flagValue = currentProvider_->lazyAnimationCallbacks();
lazyAnimationCallbacks_ = flagValue;
@@ -596,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(31, "traceTurboModulePromiseRejectionsOnAndroid");
markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid");
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
@@ -614,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(32, "useAlwaysAvailableJSErrorHandling");
markFlagAsAccessed(34, "useAlwaysAvailableJSErrorHandling");
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
useAlwaysAvailableJSErrorHandling_ = flagValue;
@@ -632,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(33, "useEditTextStockAndroidFocusBehavior");
markFlagAsAccessed(35, "useEditTextStockAndroidFocusBehavior");
flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior();
useEditTextStockAndroidFocusBehavior_ = flagValue;
@@ -650,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(34, "useFabricInterop");
markFlagAsAccessed(36, "useFabricInterop");
flagValue = currentProvider_->useFabricInterop();
useFabricInterop_ = flagValue;
@@ -668,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(35, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -686,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(36, "useOptimizedEventBatchingOnAndroid");
markFlagAsAccessed(38, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
@@ -704,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(37, "useRawPropsJsiValue");
markFlagAsAccessed(39, "useRawPropsJsiValue");
flagValue = currentProvider_->useRawPropsJsiValue();
useRawPropsJsiValue_ = flagValue;
@@ -722,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(38, "useRuntimeShadowNodeReferenceUpdate");
markFlagAsAccessed(40, "useRuntimeShadowNodeReferenceUpdate");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
@@ -740,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(39, "useTurboModuleInterop");
markFlagAsAccessed(41, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -758,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(40, "useTurboModules");
markFlagAsAccessed(42, "useTurboModules");
flagValue = currentProvider_->useTurboModules();
useTurboModules_ = flagValue;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<1b9a707ae7622e9f0a29458e6c3c12d1>>
* @generated SignedSource<<a3dd66b0308eb48a76db0c022008c431>>
*/
/**
@@ -56,6 +56,8 @@ class ReactNativeFeatureFlagsAccessor {
bool enableSynchronousStateUpdates();
bool enableUIConsistency();
bool enableViewRecycling();
bool enableViewRecyclingForText();
bool enableViewRecyclingForView();
bool excludeYogaFromRawProps();
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag();
bool fixMappingOfEventPrioritiesBetweenFabricAndReact();
@@ -84,7 +86,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 41> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 43> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> disableMountItemReorderingAndroid_;
@@ -110,6 +112,8 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enableSynchronousStateUpdates_;
std::atomic<std::optional<bool>> enableUIConsistency_;
std::atomic<std::optional<bool>> enableViewRecycling_;
std::atomic<std::optional<bool>> enableViewRecyclingForText_;
std::atomic<std::optional<bool>> enableViewRecyclingForView_;
std::atomic<std::optional<bool>> excludeYogaFromRawProps_;
std::atomic<std::optional<bool>> fixDifferentiatorEmittingUpdatesWithWrongParentTag_;
std::atomic<std::optional<bool>> fixMappingOfEventPrioritiesBetweenFabricAndReact_;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<131d8b1f15548b67a91a80f9cdb06d15>>
* @generated SignedSource<<f2527ee8120aaf0890f31a8b0f4ade39>>
*/
/**
@@ -123,6 +123,14 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableViewRecyclingForText() override {
return true;
}
bool enableViewRecyclingForView() override {
return true;
}
bool excludeYogaFromRawProps() override {
return false;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<116b4e314131a58cdc2138c6a780e41d>>
* @generated SignedSource<<f11fb76af1081648c884174db67efa74>>
*/
/**
@@ -261,6 +261,24 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::enableViewRecycling();
}
bool enableViewRecyclingForText() override {
auto value = values_["enableViewRecyclingForText"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::enableViewRecyclingForText();
}
bool enableViewRecyclingForView() override {
auto value = values_["enableViewRecyclingForView"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::enableViewRecyclingForView();
}
bool excludeYogaFromRawProps() override {
auto value = values_["excludeYogaFromRawProps"];
if (!value.isNull()) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a7741d4114f4387262e3a7611ac7e284>>
* @generated SignedSource<<f60b7ae1cc777ad7d6249665603ee63a>>
*/
/**
@@ -49,6 +49,8 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enableSynchronousStateUpdates() = 0;
virtual bool enableUIConsistency() = 0;
virtual bool enableViewRecycling() = 0;
virtual bool enableViewRecyclingForText() = 0;
virtual bool enableViewRecyclingForView() = 0;
virtual bool excludeYogaFromRawProps() = 0;
virtual bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() = 0;
virtual bool fixMappingOfEventPrioritiesBetweenFabricAndReact() = 0;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<583809a60fffb4051af3000316d145b8>>
* @generated SignedSource<<2e6ad0e2314d8618a95e96ab8677a395>>
*/
/**
@@ -164,6 +164,16 @@ bool NativeReactNativeFeatureFlags::enableViewRecycling(
return ReactNativeFeatureFlags::enableViewRecycling();
}
bool NativeReactNativeFeatureFlags::enableViewRecyclingForText(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableViewRecyclingForText();
}
bool NativeReactNativeFeatureFlags::enableViewRecyclingForView(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableViewRecyclingForView();
}
bool NativeReactNativeFeatureFlags::excludeYogaFromRawProps(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::excludeYogaFromRawProps();
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<8a136ebe8a7df3fa2283683a69f778fb>>
* @generated SignedSource<<341895c6c6a4dc1cbaa8c3712cbc5129>>
*/
/**
@@ -85,6 +85,10 @@ class NativeReactNativeFeatureFlags
bool enableViewRecycling(jsi::Runtime& runtime);
bool enableViewRecyclingForText(jsi::Runtime& runtime);
bool enableViewRecyclingForView(jsi::Runtime& runtime);
bool excludeYogaFromRawProps(jsi::Runtime& runtime);
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag(jsi::Runtime& runtime);
@@ -301,6 +301,28 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
enableViewRecyclingForText: {
defaultValue: true,
metadata: {
dateAdded: '2025-02-05',
description:
'Enables View Recycling for <Text> via ReactTextView/ReactTextViewManager.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
enableViewRecyclingForView: {
defaultValue: true,
metadata: {
dateAdded: '2025-02-05',
description:
'Enables View Recycling for <View> via ReactViewGroup/ReactViewManager.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
excludeYogaFromRawProps: {
defaultValue: false,
metadata: {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<189673854f1226119417140b4afd46e4>>
* @generated SignedSource<<35dbca51a9c45ae9a3258a94948008ba>>
* @flow strict
*/
@@ -74,6 +74,8 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
enableSynchronousStateUpdates: Getter<boolean>,
enableUIConsistency: Getter<boolean>,
enableViewRecycling: Getter<boolean>,
enableViewRecyclingForText: Getter<boolean>,
enableViewRecyclingForView: Getter<boolean>,
excludeYogaFromRawProps: Getter<boolean>,
fixDifferentiatorEmittingUpdatesWithWrongParentTag: Getter<boolean>,
fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean>,
@@ -273,6 +275,14 @@ export const enableUIConsistency: Getter<boolean> = createNativeFlagGetter('enab
* Enables View Recycling. When enabled, individual ViewManagers must still opt-in.
*/
export const enableViewRecycling: Getter<boolean> = createNativeFlagGetter('enableViewRecycling', false);
/**
* Enables View Recycling for <Text> via ReactTextView/ReactTextViewManager.
*/
export const enableViewRecyclingForText: Getter<boolean> = createNativeFlagGetter('enableViewRecyclingForText', true);
/**
* Enables View Recycling for <View> via ReactViewGroup/ReactViewManager.
*/
export const enableViewRecyclingForView: Getter<boolean> = createNativeFlagGetter('enableViewRecyclingForView', true);
/**
* When enabled, rawProps in Props will not include Yoga specific props.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<8a004cfe15509541b1aa045f219bbaca>>
* @generated SignedSource<<4eac050bb25a9ac51170508caf4dd005>>
* @flow strict
*/
@@ -48,6 +48,8 @@ export interface Spec extends TurboModule {
+enableSynchronousStateUpdates?: () => boolean;
+enableUIConsistency?: () => boolean;
+enableViewRecycling?: () => boolean;
+enableViewRecyclingForText?: () => boolean;
+enableViewRecyclingForView?: () => boolean;
+excludeYogaFromRawProps?: () => boolean;
+fixDifferentiatorEmittingUpdatesWithWrongParentTag?: () => boolean;
+fixMappingOfEventPrioritiesBetweenFabricAndReact?: () => boolean;