diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 7c41d8d7aa7..25650af04b4 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2029,7 +2029,6 @@ public class com/facebook/react/config/ReactFeatureFlags { public static field enableBridgelessArchitecture Z public static field enableCppPropsIteratorSetter Z public static field enableFabricRenderer Z - public static field enableViewRecycling Z public static field useTurboModules Z public fun ()V } 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 0fe096096d4..46f11b459ed 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 @@ -42,11 +42,6 @@ public class ReactFeatureFlags { public static boolean dispatchPointerEvents = false; - /** - * Feature Flag to enable View Recycling. When enabled, individual ViewManagers must still opt-in. - */ - public static boolean enableViewRecycling = false; - /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java index 9de211ea6b0..9ac95ccf65e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java @@ -29,7 +29,6 @@ import com.facebook.react.bridge.SoftAssertions; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.fabric.events.EventEmitterWrapper; import com.facebook.react.fabric.mounting.MountingManager.MountItemExecutor; import com.facebook.react.fabric.mounting.mountitems.MountItem; @@ -313,7 +312,7 @@ public class SurfaceMountingManager { mThemedReactContext = null; mOnViewAttachMountItems.clear(); - if (ReactFeatureFlags.enableViewRecycling) { + if (ReactNativeFeatureFlags.enableViewRecycling()) { mViewManagerRegistry.onSurfaceStopped(mSurfaceId); } FLog.e(TAG, "Surface [" + mSurfaceId + "] was stopped on SurfaceMountingManager."); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 76ceb92c47b..38a568ba2fd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -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<<5fb700b3cb0d98843505d210fc62cc82>> + * @generated SignedSource<> */ /** @@ -148,6 +148,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableUIConsistency(): Boolean = accessor.enableUIConsistency() + /** + * Enables View Recycling. When enabled, individual ViewManagers must still opt-in. + */ + @JvmStatic + public fun enableViewRecycling(): Boolean = accessor.enableViewRecycling() + /** * When enabled, rawProps in Props will not include Yoga specific props. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index a72443d6d26..3fe293142e7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -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<<4b36a495186bb73c9cd9541f72ecb9ff>> + * @generated SignedSource<<2d2f24ab93b9c2eb0b2002354f609ead>> */ /** @@ -40,6 +40,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableReportEventPaintTimeCache: Boolean? = null private var enableSynchronousStateUpdatesCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null + private var enableViewRecyclingCache: Boolean? = null private var excludeYogaFromRawPropsCache: Boolean? = null private var fetchImagesInViewPreallocationCache: Boolean? = null private var fixIncorrectScrollViewStateUpdateOnAndroidCache: Boolean? = null @@ -244,6 +245,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableViewRecycling(): Boolean { + var cached = enableViewRecyclingCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableViewRecycling() + enableViewRecyclingCache = cached + } + return cached + } + override fun excludeYogaFromRawProps(): Boolean { var cached = excludeYogaFromRawPropsCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index e899ba6af57..7fc0a0dea2d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -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<<7b542b9761fd6b5c3f00945880476616>> + * @generated SignedSource<> */ /** @@ -68,6 +68,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableUIConsistency(): Boolean + @DoNotStrip @JvmStatic public external fun enableViewRecycling(): Boolean + @DoNotStrip @JvmStatic public external fun excludeYogaFromRawProps(): Boolean @DoNotStrip @JvmStatic public external fun fetchImagesInViewPreallocation(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index f4739db997c..751cf85ea82 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -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<> + * @generated SignedSource<<4c87f6bbb603ad9a66d08600fba93554>> */ /** @@ -63,6 +63,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableUIConsistency(): Boolean = false + override fun enableViewRecycling(): Boolean = false + override fun excludeYogaFromRawProps(): Boolean = false override fun fetchImagesInViewPreallocation(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 0f89ffecef8..5a6dbbde908 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -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<<6f654101103cfdc987ade9e47a0b3d32>> + * @generated SignedSource<<9df3a3025e104c4dd9ce4fb99b8acbcd>> */ /** @@ -44,6 +44,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableReportEventPaintTimeCache: Boolean? = null private var enableSynchronousStateUpdatesCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null + private var enableViewRecyclingCache: Boolean? = null private var excludeYogaFromRawPropsCache: Boolean? = null private var fetchImagesInViewPreallocationCache: Boolean? = null private var fixIncorrectScrollViewStateUpdateOnAndroidCache: Boolean? = null @@ -268,6 +269,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableViewRecycling(): Boolean { + var cached = enableViewRecyclingCache + if (cached == null) { + cached = currentProvider.enableViewRecycling() + accessedFeatureFlags.add("enableViewRecycling") + enableViewRecyclingCache = cached + } + return cached + } + override fun excludeYogaFromRawProps(): Boolean { var cached = excludeYogaFromRawPropsCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index e4cefcc344b..5af5664e19c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -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<> + * @generated SignedSource<> */ /** @@ -63,6 +63,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableUIConsistency(): Boolean + @DoNotStrip public fun enableViewRecycling(): Boolean + @DoNotStrip public fun excludeYogaFromRawProps(): Boolean @DoNotStrip public fun fetchImagesInViewPreallocation(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java index 7ebe7909d94..198ef9907b5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java @@ -17,7 +17,7 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.mapbuffer.MapBuffer; -import com.facebook.react.config.ReactFeatureFlags; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.touch.JSResponderHandler; import com.facebook.react.touch.ReactInterceptingViewGroup; import com.facebook.react.uimanager.annotations.ReactProp; @@ -56,7 +56,7 @@ public abstract class ViewManager /** Call in constructor of concrete ViewManager class to enable. */ protected void setupViewRecycling() { - if (ReactFeatureFlags.enableViewRecycling) { + if (ReactNativeFeatureFlags.enableViewRecycling()) { mRecyclableViews = new HashMap<>(); } } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 12e971b20cf..a6c655263ff 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -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<<107da3f94e88bcd11b94dd62a71f4556>> + * @generated SignedSource<<8c7af40ab6ea0f4ea88a795d5884a07b>> */ /** @@ -159,6 +159,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableViewRecycling() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableViewRecycling"); + return method(javaProvider_); + } + bool excludeYogaFromRawProps() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("excludeYogaFromRawProps"); @@ -401,6 +407,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableUIConsistency( return ReactNativeFeatureFlags::enableUIConsistency(); } +bool JReactNativeFeatureFlagsCxxInterop::enableViewRecycling( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableViewRecycling(); +} + bool JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::excludeYogaFromRawProps(); @@ -593,6 +604,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableUIConsistency", JReactNativeFeatureFlagsCxxInterop::enableUIConsistency), + makeNativeMethod( + "enableViewRecycling", + JReactNativeFeatureFlagsCxxInterop::enableViewRecycling), makeNativeMethod( "excludeYogaFromRawProps", JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 6791ca90296..d0168cf21ad 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -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<<4182ca268eb74ffa52295cefb2c51f50>> + * @generated SignedSource<<6c0276095ccff4eb927141ce3b2c5469>> */ /** @@ -90,6 +90,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableUIConsistency( facebook::jni::alias_ref); + static bool enableViewRecycling( + facebook::jni::alias_ref); + static bool excludeYogaFromRawProps( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/BaseViewManagerTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/BaseViewManagerTest.kt index 2a39a523d9f..24ccffee48a 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/BaseViewManagerTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/BaseViewManagerTest.kt @@ -12,6 +12,7 @@ import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.JavaOnlyArray import com.facebook.react.bridge.JavaOnlyMap import com.facebook.react.bridge.WritableArray +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests import com.facebook.react.views.view.ReactViewGroup import com.facebook.react.views.view.ReactViewManager import java.util.Locale @@ -33,6 +34,7 @@ class BaseViewManagerTest { @Before fun setUp() { + ReactNativeFeatureFlagsForTests.setUp() viewManager = ReactViewManager() view = ReactViewGroup(RuntimeEnvironment.getApplication()) arguments = Mockito.mockStatic(Arguments::class.java) diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 3e4fdfa7ede..f2f154ff6ed 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -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<<003171b5ce3055ef281d041408ca146e>> + * @generated SignedSource<<763d10f3232028a26f5ed194fdb3b4f7>> */ /** @@ -101,6 +101,10 @@ bool ReactNativeFeatureFlags::enableUIConsistency() { return getAccessor().enableUIConsistency(); } +bool ReactNativeFeatureFlags::enableViewRecycling() { + return getAccessor().enableViewRecycling(); +} + bool ReactNativeFeatureFlags::excludeYogaFromRawProps() { return getAccessor().excludeYogaFromRawProps(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 761eb4f2f89..706b9718e1c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -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<<8be6a1e808bdf073829a7801545b2b8f>> + * @generated SignedSource<<14d7dd1b3690775bb8df6dc17d18c43c>> */ /** @@ -137,6 +137,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableUIConsistency(); + /** + * Enables View Recycling. When enabled, individual ViewManagers must still opt-in. + */ + RN_EXPORT static bool enableViewRecycling(); + /** * When enabled, rawProps in Props will not include Yoga specific props. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index cd804fef66c..ffc0baa9a97 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -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<<665ae1c4cf2e9ca6ede4fe2c08089263>> + * @generated SignedSource<<56f6d8ad5191b77222c9fbc5676ce697>> */ /** @@ -389,6 +389,24 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { + auto flagValue = enableViewRecycling_.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(20, "enableViewRecycling"); + + flagValue = currentProvider_->enableViewRecycling(); + enableViewRecycling_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { auto flagValue = excludeYogaFromRawProps_.load(); @@ -398,7 +416,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(20, "excludeYogaFromRawProps"); + markFlagAsAccessed(21, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::fetchImagesInViewPreallocation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "fetchImagesInViewPreallocation"); + markFlagAsAccessed(22, "fetchImagesInViewPreallocation"); flagValue = currentProvider_->fetchImagesInViewPreallocation(); fetchImagesInViewPreallocation_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::fixIncorrectScrollViewStateUpdateOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "fixIncorrectScrollViewStateUpdateOnAndroid"); + markFlagAsAccessed(23, "fixIncorrectScrollViewStateUpdateOnAndroid"); flagValue = currentProvider_->fixIncorrectScrollViewStateUpdateOnAndroid(); fixIncorrectScrollViewStateUpdateOnAndroid_ = flagValue; @@ -452,7 +470,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(23, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(24, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMissedFabricStateUpdatesOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "fixMissedFabricStateUpdatesOnAndroid"); + markFlagAsAccessed(25, "fixMissedFabricStateUpdatesOnAndroid"); flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid(); fixMissedFabricStateUpdatesOnAndroid_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(26, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "fuseboxEnabledDebug"); + markFlagAsAccessed(27, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -524,7 +542,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(27, "fuseboxEnabledRelease"); + markFlagAsAccessed(28, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(29, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -560,7 +578,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(29, "lazyAnimationCallbacks"); + markFlagAsAccessed(30, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(31, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "setAndroidLayoutDirection"); + markFlagAsAccessed(32, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -614,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(32, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -632,7 +650,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(33, "useFabricInterop"); + markFlagAsAccessed(34, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(35, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useModernRuntimeScheduler"); + markFlagAsAccessed(36, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -686,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(36, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useNewReactImageViewBackgroundDrawing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "useNewReactImageViewBackgroundDrawing"); + markFlagAsAccessed(38, "useNewReactImageViewBackgroundDrawing"); flagValue = currentProvider_->useNewReactImageViewBackgroundDrawing(); useNewReactImageViewBackgroundDrawing_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(39, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -740,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(39, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(40, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useRuntimeShadowNodeReferenceUpdateOnLayout"); + markFlagAsAccessed(41, "useRuntimeShadowNodeReferenceUpdateOnLayout"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout(); useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useStateAlignmentMechanism"); + markFlagAsAccessed(42, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; @@ -794,7 +812,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(42, "useTurboModuleInterop"); + markFlagAsAccessed(43, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 15ef5158e64..287afcc3b38 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -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<> + * @generated SignedSource<<71e34bc8db537e0b891b1fea9ffc3475>> */ /** @@ -51,6 +51,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableReportEventPaintTime(); bool enableSynchronousStateUpdates(); bool enableUIConsistency(); + bool enableViewRecycling(); bool excludeYogaFromRawProps(); bool fetchImagesInViewPreallocation(); bool fixIncorrectScrollViewStateUpdateOnAndroid(); @@ -84,7 +85,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 43> accessedFeatureFlags_; + std::array, 44> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowCollapsableChildren_; @@ -106,6 +107,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableReportEventPaintTime_; std::atomic> enableSynchronousStateUpdates_; std::atomic> enableUIConsistency_; + std::atomic> enableViewRecycling_; std::atomic> excludeYogaFromRawProps_; std::atomic> fetchImagesInViewPreallocation_; std::atomic> fixIncorrectScrollViewStateUpdateOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 78b68362efe..ae07e6ba58d 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -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<> + * @generated SignedSource<<0d95cb065819310058a7b088db43ec2d>> */ /** @@ -107,6 +107,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableViewRecycling() override { + return false; + } + bool excludeYogaFromRawProps() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 6f93a6f8988..5fc84f82d3e 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -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<<17b9a308d03c83bac5c839057a1660ef>> + * @generated SignedSource<<0e9a6d8770362cb0408f7b2c633eda38>> */ /** @@ -45,6 +45,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableReportEventPaintTime() = 0; virtual bool enableSynchronousStateUpdates() = 0; virtual bool enableUIConsistency() = 0; + virtual bool enableViewRecycling() = 0; virtual bool excludeYogaFromRawProps() = 0; virtual bool fetchImagesInViewPreallocation() = 0; virtual bool fixIncorrectScrollViewStateUpdateOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index dc943782bda..c1f7a3c1482 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -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<> + * @generated SignedSource<> */ /** @@ -137,6 +137,11 @@ bool NativeReactNativeFeatureFlags::enableUIConsistency( return ReactNativeFeatureFlags::enableUIConsistency(); } +bool NativeReactNativeFeatureFlags::enableViewRecycling( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableViewRecycling(); +} + bool NativeReactNativeFeatureFlags::excludeYogaFromRawProps( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::excludeYogaFromRawProps(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 119b0e242b3..348db881d89 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -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<<3fa54e7343d1a6c8528868d31feec5c9>> + * @generated SignedSource<> */ /** @@ -75,6 +75,8 @@ class NativeReactNativeFeatureFlags bool enableUIConsistency(jsi::Runtime& runtime); + bool enableViewRecycling(jsi::Runtime& runtime); + bool excludeYogaFromRawProps(jsi::Runtime& runtime); bool fetchImagesInViewPreallocation(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index b11a3df67bf..29d15ada5f9 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -132,6 +132,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).', }, + enableViewRecycling: { + defaultValue: false, + description: + 'Enables View Recycling. When enabled, individual ViewManagers must still opt-in.', + }, excludeYogaFromRawProps: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index e882f6e16be..088b0880984 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -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<<99fb6b4b2fef8c0c0aef3e46ed7b0632>> + * @generated SignedSource<> * @flow strict-local */ @@ -64,6 +64,7 @@ export type ReactNativeFeatureFlags = { enableReportEventPaintTime: Getter, enableSynchronousStateUpdates: Getter, enableUIConsistency: Getter, + enableViewRecycling: Getter, excludeYogaFromRawProps: Getter, fetchImagesInViewPreallocation: Getter, fixIncorrectScrollViewStateUpdateOnAndroid: Getter, @@ -229,6 +230,10 @@ export const enableSynchronousStateUpdates: Getter = createNativeFlagGe * Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution). */ export const enableUIConsistency: Getter = createNativeFlagGetter('enableUIConsistency', false); +/** + * Enables View Recycling. When enabled, individual ViewManagers must still opt-in. + */ +export const enableViewRecycling: Getter = createNativeFlagGetter('enableViewRecycling', false); /** * When enabled, rawProps in Props will not include Yoga specific props. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 8435918343e..d8b0ed7826d 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -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<<3f277725caa497e5e9636e4f2baaa371>> + * @generated SignedSource<> * @flow strict-local */ @@ -43,6 +43,7 @@ export interface Spec extends TurboModule { +enableReportEventPaintTime?: () => boolean; +enableSynchronousStateUpdates?: () => boolean; +enableUIConsistency?: () => boolean; + +enableViewRecycling?: () => boolean; +excludeYogaFromRawProps?: () => boolean; +fetchImagesInViewPreallocation?: () => boolean; +fixIncorrectScrollViewStateUpdateOnAndroid?: () => boolean;