From 47266928784eb241c43df5526c64930e2484cfb9 Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Mon, 19 Oct 2026 20:42:28 -0700 Subject: [PATCH] Enable prepared text layout by default (#59152) Summary: Turn on caching of text layout artifacts for later reuse and the Android text measurement optimizations by default, and raise the prepared layout cache size from 200 to 1000 entries. Overflow-hidden text default was already on and is unchanged. Changelog: [General][Changed] - Enable prepared text layout caching and Android text measurement optimizations by default Reviewed By: christophpurrer Differential Revision: D125768089 --- .../react-native/Libraries/Text/__tests__/Text-itest.js | 4 +++- .../featureflags/ReactNativeFeatureFlagsDefaults.kt | 8 ++++---- .../react/featureflags/ReactNativeFeatureFlagsDefaults.h | 8 ++++---- .../featureflags/ReactNativeFeatureFlags.config.js | 8 ++++---- .../src/private/featureflags/ReactNativeFeatureFlags.js | 8 ++++---- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/react-native/Libraries/Text/__tests__/Text-itest.js b/packages/react-native/Libraries/Text/__tests__/Text-itest.js index 0022c4942fef..780b9b3c7a14 100644 --- a/packages/react-native/Libraries/Text/__tests__/Text-itest.js +++ b/packages/react-native/Libraries/Text/__tests__/Text-itest.js @@ -323,7 +323,9 @@ describe('', () => { }); expect(root.getRenderedOutput({props: ['selectable']}).toJSX()).toEqual( - {TEST_TEXT}, + + {TEST_TEXT} + , ); }); 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 f4998cb8b416..50efeaf0d859 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<<669f16e131d4a5ddc026ffecc6893575>> + * @generated SignedSource<<1b7656b36283a43728ffd60af3e30d08>> */ /** @@ -53,7 +53,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableAndroidAutoOffscreenCompositingForElevation(): Boolean = false - override fun enableAndroidTextMeasurementOptimizations(): Boolean = false + override fun enableAndroidTextMeasurementOptimizations(): Boolean = true override fun enableAsyncDiskCacheCheckInMultiSourceImageAndroid(): Boolean = false @@ -117,7 +117,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enablePreallocatedPropsDiffOnInsertAndroid(): Boolean = false - override fun enablePreparedTextLayout(): Boolean = false + override fun enablePreparedTextLayout(): Boolean = true override fun enablePropsUpdateReconciliationAndroid(): Boolean = false @@ -165,7 +165,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun perfMonitorV2Enabled(): Boolean = false - override fun preparedTextCacheSize(): Double = 200.0 + override fun preparedTextCacheSize(): Double = 1000.0 override fun preventShadowTreeCommitExhaustion(): Boolean = false diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 82208e3861b9..9f8c33e4f08e 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<<52db1adfed5fd99e4ca145b50dc413a0>> + * @generated SignedSource<<4f230970c9c4fc4e5e07e4b40ed46a58>> */ /** @@ -90,7 +90,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } bool enableAndroidTextMeasurementOptimizations() override { - return false; + return true; } bool enableAsyncDiskCacheCheckInMultiSourceImageAndroid() override { @@ -218,7 +218,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } bool enablePreparedTextLayout() override { - return false; + return true; } bool enablePropsUpdateReconciliationAndroid() override { @@ -314,7 +314,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { } double preparedTextCacheSize() override { - return 200.0; + return 1000.0; } bool preventShadowTreeCommitExhaustion() override { diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 2c0786728b99..91404786cefe 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -215,7 +215,7 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, enableAndroidTextMeasurementOptimizations: { - defaultValue: false, + defaultValue: true, metadata: { dateAdded: '2025-07-01', description: @@ -556,7 +556,7 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, enablePreparedTextLayout: { - defaultValue: false, + defaultValue: true, metadata: { dateAdded: '2025-05-01', description: 'Enables caching text layout artifacts for later reuse', @@ -816,10 +816,10 @@ const definitions: FeatureFlagDefinitions = { ossReleaseStage: 'none', }, preparedTextCacheSize: { - defaultValue: 200, + defaultValue: 1000, metadata: { description: 'Number cached PreparedLayouts in TextLayoutManager cache', - expectedReleaseValue: 200, + expectedReleaseValue: 1000, purpose: 'operational', }, ossReleaseStage: 'none', diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index c190a2488b08..4f5a058f3cf7 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<> * @flow strict * @noformat */ @@ -282,7 +282,7 @@ export const enableAndroidAutoOffscreenCompositingForElevation: Getter /** * Enables various optimizations throughout the path of measuring text on Android. */ -export const enableAndroidTextMeasurementOptimizations: Getter = createNativeFlagGetter('enableAndroidTextMeasurementOptimizations', false); +export const enableAndroidTextMeasurementOptimizations: Getter = createNativeFlagGetter('enableAndroidTextMeasurementOptimizations', true); /** * Runs multi-source image disk-cache checks asynchronously on Android. */ @@ -410,7 +410,7 @@ export const enablePreallocatedPropsDiffOnInsertAndroid: Getter = creat /** * Enables caching text layout artifacts for later reuse */ -export const enablePreparedTextLayout: Getter = createNativeFlagGetter('enablePreparedTextLayout', false); +export const enablePreparedTextLayout: Getter = createNativeFlagGetter('enablePreparedTextLayout', true); /** * When enabled, Android will receive prop updates based on the differences between the last rendered shadow node and the last committed shadow node. */ @@ -506,7 +506,7 @@ export const perfMonitorV2Enabled: Getter = createNativeFlagGetter('per /** * Number cached PreparedLayouts in TextLayoutManager cache */ -export const preparedTextCacheSize: Getter = createNativeFlagGetter('preparedTextCacheSize', 200); +export const preparedTextCacheSize: Getter = createNativeFlagGetter('preparedTextCacheSize', 1000); /** * Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again. */