From 6243a33978b358a2a37bf9fc2f2b995adb03b8d6 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Thu, 12 Sep 2024 08:01:28 -0700 Subject: [PATCH] do not pass state wrapper for text during view preallocation (#46418) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46418 changelog: [internal] introduce a small performance optimisation on Android. When Paragraph is preallocated, it does not have valid C++ state. But we still send it to Android layer because it is part of a more generic pipeline. This has a cost because Android will end up using the state to update internal state on ReactTextView. To avoid this, simply add a special case to view preallocation and prevent it from sending C++ state. Reviewed By: javache Differential Revision: D62435529 fbshipit-source-id: 36b5b00a7a390432721d28d53ff8d4af76169e08 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 ++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +++- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../react/fabric/FabricMountingManager.cpp | 9 ++- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 74 ++++++++++++------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 5 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 20 files changed, 156 insertions(+), 47 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 b9ab99d8d26..eb0142288d8 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<<312da6e350ea6b96180156a341810654>> + * @generated SignedSource<> */ /** @@ -160,6 +160,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableSynchronousStateUpdates(): Boolean = accessor.enableSynchronousStateUpdates() + /** + * Text preallocation optimisation where unnecessary work is removed. + */ + @JvmStatic + public fun enableTextPreallocationOptimisation(): Boolean = accessor.enableTextPreallocationOptimisation() + /** * 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). */ 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 85e4b397cdb..f367e6d73b6 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<> + * @generated SignedSource<> */ /** @@ -42,6 +42,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null private var enableSynchronousStateUpdatesCache: Boolean? = null + private var enableTextPreallocationOptimisationCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null private var enableViewRecyclingCache: Boolean? = null private var excludeYogaFromRawPropsCache: Boolean? = null @@ -268,6 +269,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableTextPreallocationOptimisation(): Boolean { + var cached = enableTextPreallocationOptimisationCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableTextPreallocationOptimisation() + enableTextPreallocationOptimisationCache = cached + } + return cached + } + override fun enableUIConsistency(): Boolean { var cached = enableUIConsistencyCache 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 a80740223da..ba8d61642e1 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<> + * @generated SignedSource<<66a5f1eb19c081e178077b40fba27d93>> */ /** @@ -72,6 +72,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableSynchronousStateUpdates(): Boolean + @DoNotStrip @JvmStatic public external fun enableTextPreallocationOptimisation(): Boolean + @DoNotStrip @JvmStatic public external fun enableUIConsistency(): Boolean @DoNotStrip @JvmStatic public external fun enableViewRecycling(): 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 8d03bb9f647..762cc4cf036 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<<25a422b93ab27473bfccabf653b1e196>> */ /** @@ -67,6 +67,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableSynchronousStateUpdates(): Boolean = false + override fun enableTextPreallocationOptimisation(): Boolean = false + override fun enableUIConsistency(): Boolean = false override fun enableViewRecycling(): 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 fc0ea5ac10b..4410efa2203 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<<069787b84036b763c47d128e66ddd1ab>> + * @generated SignedSource<> */ /** @@ -46,6 +46,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null private var enableSynchronousStateUpdatesCache: Boolean? = null + private var enableTextPreallocationOptimisationCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null private var enableViewRecyclingCache: Boolean? = null private var excludeYogaFromRawPropsCache: Boolean? = null @@ -294,6 +295,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableTextPreallocationOptimisation(): Boolean { + var cached = enableTextPreallocationOptimisationCache + if (cached == null) { + cached = currentProvider.enableTextPreallocationOptimisation() + accessedFeatureFlags.add("enableTextPreallocationOptimisation") + enableTextPreallocationOptimisationCache = cached + } + return cached + } + override fun enableUIConsistency(): Boolean { var cached = enableUIConsistencyCache 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 d3888c60206..3880a93c555 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<<978d9e8d1129951f3c5750f95e2ff5d2>> + * @generated SignedSource<<2e20df15ed5c75e0749eeead23b3c9dc>> */ /** @@ -67,6 +67,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableSynchronousStateUpdates(): Boolean + @DoNotStrip public fun enableTextPreallocationOptimisation(): Boolean + @DoNotStrip public fun enableUIConsistency(): Boolean @DoNotStrip public fun enableViewRecycling(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index 1515bd60909..bec4f2c42bf 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -847,7 +847,14 @@ void FabricMountingManager::preallocateShadowView( // We DO want to hold onto C object from Java, since we don't know the // lifetime of the Java object jni::local_ref javaStateWrapper = nullptr; - if (shadowView.state != nullptr) { + + // Paragraph only has a dummy state during view preallocation. + // Updating state on Android side has a cost and doing it unnecessarily for + // dummy state is wasteful. + bool preventPassingStateWrapperForText = + ReactNativeFeatureFlags::enableTextPreallocationOptimisation() && + strcmp(shadowView.componentName, "Paragraph") == 0; + if (shadowView.state != nullptr && !preventPassingStateWrapperForText) { javaStateWrapper = StateWrapperImpl::newObjectJavaArgs(); StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper); cStateWrapper->setState(shadowView.state); 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 901090538b4..22f0c9cba38 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<<63ef974f6ed666553bc0be593730a08e>> + * @generated SignedSource<<4ae4df54833e6fc817d73fe7cb7d1887>> */ /** @@ -171,6 +171,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableTextPreallocationOptimisation() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableTextPreallocationOptimisation"); + return method(javaProvider_); + } + bool enableUIConsistency() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableUIConsistency"); @@ -447,6 +453,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates( return ReactNativeFeatureFlags::enableSynchronousStateUpdates(); } +bool JReactNativeFeatureFlagsCxxInterop::enableTextPreallocationOptimisation( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableTextPreallocationOptimisation(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableUIConsistency( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableUIConsistency(); @@ -665,6 +676,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableSynchronousStateUpdates", JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates), + makeNativeMethod( + "enableTextPreallocationOptimisation", + JReactNativeFeatureFlagsCxxInterop::enableTextPreallocationOptimisation), makeNativeMethod( "enableUIConsistency", JReactNativeFeatureFlagsCxxInterop::enableUIConsistency), 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 891ddb8f140..0ab8b6d104c 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<> + * @generated SignedSource<> */ /** @@ -96,6 +96,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableSynchronousStateUpdates( facebook::jni::alias_ref); + static bool enableTextPreallocationOptimisation( + facebook::jni::alias_ref); + static bool enableUIConsistency( 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 b33f8453628..2cebcccb90b 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<<7c97c370b2f453691c153fb370bea149>> + * @generated SignedSource<<5df8c423af27ec25003d26a67ec1ef56>> */ /** @@ -109,6 +109,10 @@ bool ReactNativeFeatureFlags::enableSynchronousStateUpdates() { return getAccessor().enableSynchronousStateUpdates(); } +bool ReactNativeFeatureFlags::enableTextPreallocationOptimisation() { + return getAccessor().enableTextPreallocationOptimisation(); +} + bool ReactNativeFeatureFlags::enableUIConsistency() { return getAccessor().enableUIConsistency(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 8ab9be02cce..9047a887628 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<> + * @generated SignedSource<<631e0b3e36325d36803b7e6fbefe2644>> */ /** @@ -147,6 +147,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableSynchronousStateUpdates(); + /** + * Text preallocation optimisation where unnecessary work is removed. + */ + RN_EXPORT static bool enableTextPreallocationOptimisation(); + /** * 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). */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index edf82b33f94..1be2288db32 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<<0ea766879653efe26784aacb9823872e>> + * @generated SignedSource<<627aa945212c83aacd6a479c7c8857b2>> */ /** @@ -425,6 +425,24 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() { + auto flagValue = enableTextPreallocationOptimisation_.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(22, "enableTextPreallocationOptimisation"); + + flagValue = currentProvider_->enableTextPreallocationOptimisation(); + enableTextPreallocationOptimisation_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { auto flagValue = enableUIConsistency_.load(); @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableUIConsistency"); + markFlagAsAccessed(23, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -452,7 +470,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(23, "enableViewRecycling"); + markFlagAsAccessed(24, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "excludeYogaFromRawProps"); + markFlagAsAccessed(25, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -488,7 +506,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(25, "fetchImagesInViewPreallocation"); + markFlagAsAccessed(26, "fetchImagesInViewPreallocation"); flagValue = currentProvider_->fetchImagesInViewPreallocation(); fetchImagesInViewPreallocation_ = flagValue; @@ -506,7 +524,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(26, "fixIncorrectScrollViewStateUpdateOnAndroid"); + markFlagAsAccessed(27, "fixIncorrectScrollViewStateUpdateOnAndroid"); flagValue = currentProvider_->fixIncorrectScrollViewStateUpdateOnAndroid(); fixIncorrectScrollViewStateUpdateOnAndroid_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -542,7 +560,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(28, "fixMissedFabricStateUpdatesOnAndroid"); + markFlagAsAccessed(29, "fixMissedFabricStateUpdatesOnAndroid"); flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid(); fixMissedFabricStateUpdatesOnAndroid_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -578,7 +596,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(30, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(31, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -596,7 +614,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(31, "fuseboxEnabledDebug"); + markFlagAsAccessed(32, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -614,7 +632,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(32, "fuseboxEnabledRelease"); + markFlagAsAccessed(33, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -632,7 +650,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(33, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(34, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -650,7 +668,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(34, "lazyAnimationCallbacks"); + markFlagAsAccessed(35, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -668,7 +686,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(35, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(36, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -686,7 +704,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(36, "setAndroidLayoutDirection"); + markFlagAsAccessed(37, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -704,7 +722,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(37, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(38, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -722,7 +740,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(38, "useFabricInterop"); + markFlagAsAccessed(39, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -740,7 +758,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(39, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -758,7 +776,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(40, "useModernRuntimeScheduler"); + markFlagAsAccessed(41, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -776,7 +794,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(41, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(42, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -794,7 +812,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(42, "useNewReactImageViewBackgroundDrawing"); + markFlagAsAccessed(43, "useNewReactImageViewBackgroundDrawing"); flagValue = currentProvider_->useNewReactImageViewBackgroundDrawing(); useNewReactImageViewBackgroundDrawing_ = flagValue; @@ -812,7 +830,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(43, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(44, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(45, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -848,7 +866,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(45, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(46, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -866,7 +884,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(46, "useRuntimeShadowNodeReferenceUpdateOnLayout"); + markFlagAsAccessed(47, "useRuntimeShadowNodeReferenceUpdateOnLayout"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout(); useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue; @@ -884,7 +902,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(47, "useStateAlignmentMechanism"); + markFlagAsAccessed(48, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; @@ -902,7 +920,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(48, "useTurboModuleInterop"); + markFlagAsAccessed(49, "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 0476e17e8d6..b5b09e8e8a1 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<<7943d0be377deed21ddec9964d952db9>> + * @generated SignedSource<<2295b8f3aa175d73c9d8869a6bc9d6bc>> */ /** @@ -53,6 +53,7 @@ class ReactNativeFeatureFlagsAccessor { bool enablePropsUpdateReconciliationAndroid(); bool enableReportEventPaintTime(); bool enableSynchronousStateUpdates(); + bool enableTextPreallocationOptimisation(); bool enableUIConsistency(); bool enableViewRecycling(); bool excludeYogaFromRawProps(); @@ -90,7 +91,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 49> accessedFeatureFlags_; + std::array, 50> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; @@ -114,6 +115,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enablePropsUpdateReconciliationAndroid_; std::atomic> enableReportEventPaintTime_; std::atomic> enableSynchronousStateUpdates_; + std::atomic> enableTextPreallocationOptimisation_; std::atomic> enableUIConsistency_; std::atomic> enableViewRecycling_; std::atomic> excludeYogaFromRawProps_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 788d0e7d064..0869fe9adcc 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<> */ /** @@ -115,6 +115,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableTextPreallocationOptimisation() override { + return false; + } + bool enableUIConsistency() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 47e95f5a8b3..8a26c078225 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<<4731cdde78972b5a0fac6dffc7c1673e>> + * @generated SignedSource<<5b57e1d4e6a713cd4da5890b29f746a3>> */ /** @@ -47,6 +47,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enablePropsUpdateReconciliationAndroid() = 0; virtual bool enableReportEventPaintTime() = 0; virtual bool enableSynchronousStateUpdates() = 0; + virtual bool enableTextPreallocationOptimisation() = 0; virtual bool enableUIConsistency() = 0; virtual bool enableViewRecycling() = 0; virtual bool excludeYogaFromRawProps() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index a8f6d180df8..de263d8f8ee 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<<462f08327661efce8cff4747045e51c0>> */ /** @@ -147,6 +147,11 @@ bool NativeReactNativeFeatureFlags::enableSynchronousStateUpdates( return ReactNativeFeatureFlags::enableSynchronousStateUpdates(); } +bool NativeReactNativeFeatureFlags::enableTextPreallocationOptimisation( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableTextPreallocationOptimisation(); +} + bool NativeReactNativeFeatureFlags::enableUIConsistency( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableUIConsistency(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 2ae81fa04f6..cff6080750b 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<<653edeb6896f7803d7617b330b23683f>> + * @generated SignedSource<<500b64c27ce4976086f60ea767926b25>> */ /** @@ -79,6 +79,8 @@ class NativeReactNativeFeatureFlags bool enableSynchronousStateUpdates(jsi::Runtime& runtime); + bool enableTextPreallocationOptimisation(jsi::Runtime& runtime); + bool enableUIConsistency(jsi::Runtime& runtime); bool enableViewRecycling(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 5ddc036de1b..3792f948201 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -140,6 +140,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread).', }, + enableTextPreallocationOptimisation: { + defaultValue: false, + description: + 'Text preallocation optimisation where unnecessary work is removed.', + }, enableUIConsistency: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index dc1a2ce1e61..9c97dc3812d 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<> + * @generated SignedSource<<2333bd2bbcab9d50e4cb23d1b7d42021>> * @flow strict-local */ @@ -69,6 +69,7 @@ export type ReactNativeFeatureFlags = { enablePropsUpdateReconciliationAndroid: Getter, enableReportEventPaintTime: Getter, enableSynchronousStateUpdates: Getter, + enableTextPreallocationOptimisation: Getter, enableUIConsistency: Getter, enableViewRecycling: Getter, excludeYogaFromRawProps: Getter, @@ -261,6 +262,10 @@ export const enableReportEventPaintTime: Getter = createNativeFlagGette * Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread). */ export const enableSynchronousStateUpdates: Getter = createNativeFlagGetter('enableSynchronousStateUpdates', false); +/** + * Text preallocation optimisation where unnecessary work is removed. + */ +export const enableTextPreallocationOptimisation: Getter = createNativeFlagGetter('enableTextPreallocationOptimisation', false); /** * 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). */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index f0bb077075a..0d134a152b7 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<<901a2d15357b642b74edcf588e35de40>> + * @generated SignedSource<> * @flow strict-local */ @@ -45,6 +45,7 @@ export interface Spec extends TurboModule { +enablePropsUpdateReconciliationAndroid?: () => boolean; +enableReportEventPaintTime?: () => boolean; +enableSynchronousStateUpdates?: () => boolean; + +enableTextPreallocationOptimisation?: () => boolean; +enableUIConsistency?: () => boolean; +enableViewRecycling?: () => boolean; +excludeYogaFromRawProps?: () => boolean;