From ab82f97114545fbd320c0ef9d21fefa48a44bd48 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 2 Mar 2026 09:32:52 -0800 Subject: [PATCH] Pre-allocate mutation vectors in Differentiator to reduce reallocation overhead (#55819) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/55819 Changelog: [Internal] speed up differentiator | Test | Before (ms) | After (ms) | Improvement | |-------------------------------|-------------|------------|-------------| | 100 uncollapsable views | 3.0 | 2.7 | +10% | | 1000 uncollapsable views | 91.1 | 50.5 | +45% | | 100 views w/ many props | 9.8 | 9.2 | +6% | | 1000 views w/ many props | 147.4 | 116.7 | +21% | | 1500 views w/ many props | 143.1 | 136.7 | +5% | Reviewed By: mdvacca Differential Revision: D94096006 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 152 ++++++++++-------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../renderer/mounting/Differentiator.cpp | 38 ++++- .../ReactNativeFeatureFlags.config.js | 11 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 240 insertions(+), 87 deletions(-) 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 a2295ba531e..a66fb344c78 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<<156d4f5f35037184b6fc61ff1d856028>> + * @generated SignedSource<<2ca6b65f1103a486e4e5a006de629e76>> */ /** @@ -144,6 +144,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableDestroyShadowTreeRevisionAsync(): Boolean = accessor.enableDestroyShadowTreeRevisionAsync() + /** + * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. + */ + @JvmStatic + public fun enableDifferentiatorMutationVectorPreallocation(): Boolean = accessor.enableDifferentiatorMutationVectorPreallocation() + /** * When enabled a subset of components will avoid double measurement on Android. */ 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 df54de17065..164b90ee3e9 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<<0875d5e54d884a26d37bb4eb2acc57d5>> + * @generated SignedSource<<202662ab1c26ed104cfe837162d4f9a2>> */ /** @@ -39,6 +39,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null + private var enableDifferentiatorMutationVectorPreallocationCache: Boolean? = null private var enableDoubleMeasurementFixAndroidCache: Boolean? = null private var enableEagerMainQueueModulesOnIOSCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null @@ -277,6 +278,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableDifferentiatorMutationVectorPreallocation(): Boolean { + var cached = enableDifferentiatorMutationVectorPreallocationCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableDifferentiatorMutationVectorPreallocation() + enableDifferentiatorMutationVectorPreallocationCache = cached + } + return cached + } + override fun enableDoubleMeasurementFixAndroid(): Boolean { var cached = enableDoubleMeasurementFixAndroidCache 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 a9e7550867b..0ba312d6258 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<<948a9beebe2ff00791a03455eb774eee>> + * @generated SignedSource<<03f5b76fefda14757a43414f6624601a>> */ /** @@ -66,6 +66,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableDestroyShadowTreeRevisionAsync(): Boolean + @DoNotStrip @JvmStatic public external fun enableDifferentiatorMutationVectorPreallocation(): Boolean + @DoNotStrip @JvmStatic public external fun enableDoubleMeasurementFixAndroid(): Boolean @DoNotStrip @JvmStatic public external fun enableEagerMainQueueModulesOnIOS(): 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 b7e15d74090..01469ff2539 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<<89c61520177334f93c65ff92c2fc74a6>> + * @generated SignedSource<<7713ee7b0947f0ae8c66b73413a7f226>> */ /** @@ -61,6 +61,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableDestroyShadowTreeRevisionAsync(): Boolean = false + override fun enableDifferentiatorMutationVectorPreallocation(): Boolean = false + override fun enableDoubleMeasurementFixAndroid(): Boolean = false override fun enableEagerMainQueueModulesOnIOS(): 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 48cb60dc589..1ce18fbaf47 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<<669708c311abe9ffc8f7783219e2baad>> + * @generated SignedSource<<79cf67c605a76059f010cf2ccd0ec64b>> */ /** @@ -43,6 +43,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null + private var enableDifferentiatorMutationVectorPreallocationCache: Boolean? = null private var enableDoubleMeasurementFixAndroidCache: Boolean? = null private var enableEagerMainQueueModulesOnIOSCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null @@ -300,6 +301,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableDifferentiatorMutationVectorPreallocation(): Boolean { + var cached = enableDifferentiatorMutationVectorPreallocationCache + if (cached == null) { + cached = currentProvider.enableDifferentiatorMutationVectorPreallocation() + accessedFeatureFlags.add("enableDifferentiatorMutationVectorPreallocation") + enableDifferentiatorMutationVectorPreallocationCache = cached + } + return cached + } + override fun enableDoubleMeasurementFixAndroid(): Boolean { var cached = enableDoubleMeasurementFixAndroidCache 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 e0b05b9dde3..59b5af3095b 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<<655d1ff3caeb3d8e95d44176d65b951b>> */ /** @@ -61,6 +61,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableDestroyShadowTreeRevisionAsync(): Boolean + @DoNotStrip public fun enableDifferentiatorMutationVectorPreallocation(): Boolean + @DoNotStrip public fun enableDoubleMeasurementFixAndroid(): Boolean @DoNotStrip public fun enableEagerMainQueueModulesOnIOS(): Boolean 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 7a60a11c727..5467c7072e8 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<<0b95d68522d63d51d3e524aeecff246a>> + * @generated SignedSource<<175e48107d9bd1d713a4da0a252a58bf>> */ /** @@ -153,6 +153,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableDifferentiatorMutationVectorPreallocation() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableDifferentiatorMutationVectorPreallocation"); + return method(javaProvider_); + } + bool enableDoubleMeasurementFixAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableDoubleMeasurementFixAndroid"); @@ -648,6 +654,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync( return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync(); } +bool JReactNativeFeatureFlagsCxxInterop::enableDifferentiatorMutationVectorPreallocation( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid(); @@ -1066,6 +1077,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableDestroyShadowTreeRevisionAsync", JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync), + makeNativeMethod( + "enableDifferentiatorMutationVectorPreallocation", + JReactNativeFeatureFlagsCxxInterop::enableDifferentiatorMutationVectorPreallocation), makeNativeMethod( "enableDoubleMeasurementFixAndroid", JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid), 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 67889af8a63..69cb7c48e47 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<<6b7e2af51ba9d64ae4e474dfa104a7c3>> + * @generated SignedSource<> */ /** @@ -87,6 +87,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableDestroyShadowTreeRevisionAsync( facebook::jni::alias_ref); + static bool enableDifferentiatorMutationVectorPreallocation( + facebook::jni::alias_ref); + static bool enableDoubleMeasurementFixAndroid( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 0c045bcf92d..08bfc040f3d 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<<08a361f2ffac6a0496adac1d4c3e4726>> + * @generated SignedSource<<5208616bc5d84f040ad0fa5e85acd6c4>> */ /** @@ -102,6 +102,10 @@ bool ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync() { return getAccessor().enableDestroyShadowTreeRevisionAsync(); } +bool ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation() { + return getAccessor().enableDifferentiatorMutationVectorPreallocation(); +} + bool ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid() { return getAccessor().enableDoubleMeasurementFixAndroid(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index af8e15b1e6e..731038a3456 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<<0bbe4d41581432dfad7adbc2db133d00>> + * @generated SignedSource<<1cbe2158c5242b2980ddafafe9084d7c>> */ /** @@ -134,6 +134,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableDestroyShadowTreeRevisionAsync(); + /** + * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. + */ + RN_EXPORT static bool enableDifferentiatorMutationVectorPreallocation(); + /** * When enabled a subset of components will avoid double measurement on Android. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index de6c64c0be1..90f98c98f1d 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<<3dd9492ca660ad6350ce6ee4a9b5e310>> + * @generated SignedSource<> */ /** @@ -371,6 +371,24 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableDifferentiatorMutationVectorPreallocation() { + auto flagValue = enableDifferentiatorMutationVectorPreallocation_.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(19, "enableDifferentiatorMutationVectorPreallocation"); + + flagValue = currentProvider_->enableDifferentiatorMutationVectorPreallocation(); + enableDifferentiatorMutationVectorPreallocation_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { auto flagValue = enableDoubleMeasurementFixAndroid_.load(); @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(20, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerMainQueueModulesOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableEagerMainQueueModulesOnIOS"); + markFlagAsAccessed(21, "enableEagerMainQueueModulesOnIOS"); flagValue = currentProvider_->enableEagerMainQueueModulesOnIOS(); enableEagerMainQueueModulesOnIOS_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableEagerRootViewAttachment"); + markFlagAsAccessed(22, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(23, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranching() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableFabricCommitBranching"); + markFlagAsAccessed(24, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableFabricLogs"); + markFlagAsAccessed(25, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableFabricRenderer"); + markFlagAsAccessed(26, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(27, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(28, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(29, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(30, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingJNIBatchingAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableImagePrefetchingJNIBatchingAndroid"); + markFlagAsAccessed(31, "enableImagePrefetchingJNIBatchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingJNIBatchingAndroid(); enableImagePrefetchingJNIBatchingAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingOnUiThreadAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableImagePrefetchingOnUiThreadAndroid"); + markFlagAsAccessed(32, "enableImagePrefetchingOnUiThreadAndroid"); flagValue = currentProvider_->enableImagePrefetchingOnUiThreadAndroid(); enableImagePrefetchingOnUiThreadAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(33, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableImperativeFocus"); + markFlagAsAccessed(34, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(35, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(36, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableKeyEvents"); + markFlagAsAccessed(37, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(38, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(39, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(40, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(41, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableNativeCSSParsing"); + markFlagAsAccessed(42, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableNetworkEventReporting"); + markFlagAsAccessed(43, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enablePreparedTextLayout"); + markFlagAsAccessed(44, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(45, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(46, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableViewCulling"); + markFlagAsAccessed(47, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewRecycling"); + markFlagAsAccessed(48, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableViewRecyclingForImage"); + markFlagAsAccessed(49, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(50, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableViewRecyclingForText"); + markFlagAsAccessed(51, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableViewRecyclingForView"); + markFlagAsAccessed(52, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(53, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(54, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::fixFindShadowNodeByTagRaceCondition() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "fixFindShadowNodeByTagRaceCondition"); + markFlagAsAccessed(55, "fixFindShadowNodeByTagRaceCondition"); flagValue = currentProvider_->fixFindShadowNodeByTagRaceCondition(); fixFindShadowNodeByTagRaceCondition_ = flagValue; @@ -1028,7 +1046,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(55, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(56, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::fixTextClippingAndroid15useBoundsForWidth( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "fixTextClippingAndroid15useBoundsForWidth"); + markFlagAsAccessed(57, "fixTextClippingAndroid15useBoundsForWidth"); flagValue = currentProvider_->fixTextClippingAndroid15useBoundsForWidth(); fixTextClippingAndroid15useBoundsForWidth_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(58, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1082,7 +1100,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(58, "fuseboxEnabledRelease"); + markFlagAsAccessed(59, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1100,7 +1118,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(59, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(60, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(61, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(62, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "perfIssuesEnabled"); + markFlagAsAccessed(63, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "perfMonitorV2Enabled"); + markFlagAsAccessed(64, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1190,7 +1208,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "preparedTextCacheSize"); + markFlagAsAccessed(65, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(66, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(67, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(68, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(69, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipToPaddingWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "syncAndroidClipToPaddingWithOverflow"); + markFlagAsAccessed(70, "syncAndroidClipToPaddingWithOverflow"); flagValue = currentProvider_->syncAndroidClipToPaddingWithOverflow(); syncAndroidClipToPaddingWithOverflow_ = flagValue; @@ -1298,7 +1316,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(70, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(71, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1352,7 +1370,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(73, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(74, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1370,7 +1388,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(74, "useFabricInterop"); + markFlagAsAccessed(75, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1388,7 +1406,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(75, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(76, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "useNestedScrollViewAndroid"); + markFlagAsAccessed(77, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "useSharedAnimatedBackend"); + markFlagAsAccessed(78, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(79, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1460,7 +1478,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(79, "useTurboModuleInterop"); + markFlagAsAccessed(80, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1478,7 +1496,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(80, "useTurboModules"); + markFlagAsAccessed(81, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1496,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::useUnorderedMapInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "useUnorderedMapInDifferentiator"); + markFlagAsAccessed(82, "useUnorderedMapInDifferentiator"); flagValue = currentProvider_->useUnorderedMapInDifferentiator(); useUnorderedMapInDifferentiator_ = flagValue; @@ -1514,7 +1532,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "viewCullingOutsetRatio"); + markFlagAsAccessed(83, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "viewTransitionEnabled"); + markFlagAsAccessed(84, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1550,7 +1568,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "virtualViewPrerenderRatio"); + markFlagAsAccessed(85, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index b3784c81fe6..454d483bf89 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<<2cb2c124f044468f96262086bfac5aad>> + * @generated SignedSource<> */ /** @@ -51,6 +51,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableCppPropsIteratorSetter(); bool enableCustomFocusSearchOnClippedElementsAndroid(); bool enableDestroyShadowTreeRevisionAsync(); + bool enableDifferentiatorMutationVectorPreallocation(); bool enableDoubleMeasurementFixAndroid(); bool enableEagerMainQueueModulesOnIOS(); bool enableEagerRootViewAttachment(); @@ -128,7 +129,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 85> accessedFeatureFlags_; + std::array, 86> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -149,6 +150,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableCppPropsIteratorSetter_; std::atomic> enableCustomFocusSearchOnClippedElementsAndroid_; std::atomic> enableDestroyShadowTreeRevisionAsync_; + std::atomic> enableDifferentiatorMutationVectorPreallocation_; std::atomic> enableDoubleMeasurementFixAndroid_; std::atomic> enableEagerMainQueueModulesOnIOS_; std::atomic> enableEagerRootViewAttachment_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 75ba8e143e4..1807361bc1f 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<<7f1c4037925fc37dcdcba51df968d503>> + * @generated SignedSource<> */ /** @@ -103,6 +103,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableDifferentiatorMutationVectorPreallocation() override { + return false; + } + bool enableDoubleMeasurementFixAndroid() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 62a9247ac77..9b51cd8ea33 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.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<> */ /** @@ -216,6 +216,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableDestroyShadowTreeRevisionAsync(); } + bool enableDifferentiatorMutationVectorPreallocation() override { + auto value = values_["enableDifferentiatorMutationVectorPreallocation"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableDifferentiatorMutationVectorPreallocation(); + } + bool enableDoubleMeasurementFixAndroid() override { auto value = values_["enableDoubleMeasurementFixAndroid"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index f1cff605711..0c6e9ae47a4 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<<43e301c5028a2ed195e2a3d0a4cd0ab3>> + * @generated SignedSource<> */ /** @@ -44,6 +44,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableCppPropsIteratorSetter() = 0; virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0; virtual bool enableDestroyShadowTreeRevisionAsync() = 0; + virtual bool enableDifferentiatorMutationVectorPreallocation() = 0; virtual bool enableDoubleMeasurementFixAndroid() = 0; virtual bool enableEagerMainQueueModulesOnIOS() = 0; virtual bool enableEagerRootViewAttachment() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 34101508393..bb1057121ce 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<<006c43555032f785207c6c013f1974f5>> + * @generated SignedSource<> */ /** @@ -139,6 +139,11 @@ bool NativeReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync( return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync(); } +bool NativeReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableDifferentiatorMutationVectorPreallocation(); +} + bool NativeReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 6675417c0e5..8e919af8df5 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<<525d64b15e1b72440743363280116c6a>> + * @generated SignedSource<<567578eba7383f26c5d745c57d110e61>> */ /** @@ -74,6 +74,8 @@ class NativeReactNativeFeatureFlags bool enableDestroyShadowTreeRevisionAsync(jsi::Runtime& runtime); + bool enableDifferentiatorMutationVectorPreallocation(jsi::Runtime& runtime); + bool enableDoubleMeasurementFixAndroid(jsi::Runtime& runtime); bool enableEagerMainQueueModulesOnIOS(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp index d3c7c92376f..89f27bf71f9 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -884,6 +884,20 @@ static void calculateShadowViewMutations( // Lists of mutations auto mutationContainer = OrderedMutationInstructionContainer{}; + if (ReactNativeFeatureFlags:: + enableDifferentiatorMutationVectorPreallocation()) { + // Pre-allocate mutation sub-vectors based on expected child count to avoid + // repeated reallocations during diffing. + size_t estimatedSize = std::max(oldChildPairs.size(), newChildPairs.size()); + mutationContainer.createMutations.reserve(estimatedSize); + mutationContainer.deleteMutations.reserve(estimatedSize); + mutationContainer.insertMutations.reserve(estimatedSize); + mutationContainer.removeMutations.reserve(estimatedSize); + mutationContainer.updateMutations.reserve(estimatedSize); + mutationContainer.downwardMutations.reserve(estimatedSize); + mutationContainer.destructiveDownwardMutations.reserve(estimatedSize); + } + DEBUG_LOGS({ LOG(ERROR) << "Differ Entry: Child Pairs of node: [" << parentTag << "]"; LOG(ERROR) << "> Old Child Pairs: " << oldChildPairs; @@ -1313,6 +1327,19 @@ static void calculateShadowViewMutations( } } + if (ReactNativeFeatureFlags:: + enableDifferentiatorMutationVectorPreallocation()) { + mutations.reserve( + mutations.size() + + mutationContainer.destructiveDownwardMutations.size() + + mutationContainer.updateMutations.size() + + mutationContainer.removeMutations.size() + + mutationContainer.deleteMutations.size() + + mutationContainer.createMutations.size() + + mutationContainer.downwardMutations.size() + + mutationContainer.insertMutations.size()); + } + // All mutations in an optimal order: std::move( mutationContainer.destructiveDownwardMutations.begin(), @@ -1358,7 +1385,6 @@ ShadowViewMutation::List calculateShadowViewMutations( ViewNodePairScope innerViewNodePairScope{}; auto mutations = ShadowViewMutation::List{}; - mutations.reserve(256); auto oldRootShadowView = ShadowView(oldRootShadowNode); auto newRootShadowView = ShadowView(newRootShadowNode); @@ -1381,6 +1407,16 @@ ShadowViewMutation::List calculateShadowViewMutations( false /* allowFlattened */, {} /* layoutOffset */, {} /* cullingContext */); + + if (ReactNativeFeatureFlags:: + enableDifferentiatorMutationVectorPreallocation()) { + // Estimate ~2 mutations per view (create + insert or remove + delete). + mutations.reserve( + std::max(size_t(256), (sliceOne.size() + sliceTwo.size()) * 2)); + } else { + mutations.reserve(256); + } + calculateShadowViewMutations( innerViewNodePairScope, mutations, diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index f94c57d63e4..957047b5bcb 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -255,6 +255,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableDifferentiatorMutationVectorPreallocation: { + defaultValue: false, + metadata: { + dateAdded: '2026-02-28', + description: + 'Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableDoubleMeasurementFixAndroid: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a5d41dc0b7d..ed2200b5c99 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<<03688450419694f6d3f4fc709df4de9a>> + * @generated SignedSource<<6c49874d2e5f3f9dfa6c64945026f4b7>> * @flow strict * @noformat */ @@ -67,6 +67,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableCppPropsIteratorSetter: Getter, enableCustomFocusSearchOnClippedElementsAndroid: Getter, enableDestroyShadowTreeRevisionAsync: Getter, + enableDifferentiatorMutationVectorPreallocation: Getter, enableDoubleMeasurementFixAndroid: Getter, enableEagerMainQueueModulesOnIOS: Getter, enableEagerRootViewAttachment: Getter, @@ -280,6 +281,10 @@ export const enableCustomFocusSearchOnClippedElementsAndroid: Getter = * Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work. */ export const enableDestroyShadowTreeRevisionAsync: Getter = createNativeFlagGetter('enableDestroyShadowTreeRevisionAsync', false); +/** + * Pre-allocate mutation vectors in the Differentiator to reduce reallocation overhead during shadow view diffing. + */ +export const enableDifferentiatorMutationVectorPreallocation: Getter = createNativeFlagGetter('enableDifferentiatorMutationVectorPreallocation', false); /** * When enabled a subset of components will avoid double measurement on Android. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 4b47cc872f5..6c01f3b3bba 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<<2955ab3f744af8b5cdf587312ba423d7>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -44,6 +44,7 @@ export interface Spec extends TurboModule { +enableCppPropsIteratorSetter?: () => boolean; +enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean; +enableDestroyShadowTreeRevisionAsync?: () => boolean; + +enableDifferentiatorMutationVectorPreallocation?: () => boolean; +enableDoubleMeasurementFixAndroid?: () => boolean; +enableEagerMainQueueModulesOnIOS?: () => boolean; +enableEagerRootViewAttachment?: () => boolean;