diff --git a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js index 0db6d3415496..f9009af428a7 100644 --- a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js +++ b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js @@ -47,6 +47,9 @@ const getConstantsForViewManager: ?(viewManagerName: string) => ?Object = const getDefaultEventTypes: ?() => Object = global.RN$LegacyInterop_UIManager_getDefaultEventTypes; +const uiManagerOptimization = global.RN$discordUiManagerOptimization ?? 0; +const shouldLoadViewManagerConstantsOnDemand = uiManagerOptimization === 2; + const getDefaultEventTypesCached = (function () { let wasCalledOnce = false; let result = null; @@ -260,6 +263,10 @@ const UIManagerJSPlatformAPIs = Platform.select({ }, }); +// Building every eagerly registered view manager's constants up front is slow. +// In the on-demand experiment, cache only the view managers JS actually uses. +const viewManagerConfigs: {[viewManagerName: string]: ?Object} = {}; + const UIManagerJS: UIManagerJSInterface & {[string]: any} = { ...UIManagerJSOverridenAPIs, ...UIManagerJSDeprecatedPlatformAPIs, @@ -267,6 +274,17 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { ...UIManagerJSUnusedInNewArchAPIs, getViewManagerConfig: (viewManagerName: string): unknown => { if (getUIManagerConstants) { + if (shouldLoadViewManagerConstantsOnDemand) { + if ( + viewManagerConfigs[viewManagerName] == null && + UIManagerJS.getConstantsForViewManager + ) { + viewManagerConfigs[viewManagerName] = + UIManagerJS.getConstantsForViewManager(viewManagerName); + } + return viewManagerConfigs[viewManagerName]; + } + const constants = getUIManagerConstantsCached(); if ( !constants[viewManagerName] && @@ -396,7 +414,7 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { }, }; -if (getUIManagerConstants) { +if (getUIManagerConstants && !shouldLoadViewManagerConstantsOnDemand) { Object.keys(getUIManagerConstantsCached()).forEach(viewConfigName => { UIManagerJS[viewConfigName] = getUIManagerConstantsCached()[viewConfigName]; }); diff --git a/packages/react-native/Libraries/ReactNative/UIManager.js b/packages/react-native/Libraries/ReactNative/UIManager.js index 3d2729530286..933e978194b5 100644 --- a/packages/react-native/Libraries/ReactNative/UIManager.js +++ b/packages/react-native/Libraries/ReactNative/UIManager.js @@ -23,9 +23,26 @@ const UIManagerImpl: UIManagerJSInterface = ? require('./BridgelessUIManager').default : require('./PaperUIManager').default; -// $FlowFixMe[cannot-spread-interface] -const UIManager: UIManagerJSInterface = { - ...UIManagerImpl, +const UIManagerOverrides = { + /** + * Determines the location on screen, width, and height of the given view and + * returns the values via an async callback. If successful, the callback will + * be called with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * Note that these measurements are not available until after the rendering + * has been completed in native. If you need the measurements as soon as + * possible, consider using the [`onLayout` + * prop](docs/view.html#onlayout) instead. + * + * @deprecated Use `ref.measure` instead. + */ measure( reactTag: number, callback: ( @@ -190,4 +207,28 @@ const UIManager: UIManagerJSInterface = { }, }; +let UIManager: UIManagerJSInterface; +const uiManagerOptimization = global.RN$discordUiManagerOptimization ?? 0; +const shouldPreserveLazyProperties = uiManagerOptimization === 1; + +if (shouldPreserveLazyProperties) { + // Copy property descriptors instead of spreading UIManagerImpl. In Bridgeless + // mode, UIManagerImpl may define enumerable lazy ViewManager getters. Spreading + // the object would invoke every getter during module initialization. + // $FlowFixMe[incompatible-type] Flow cannot infer properties from descriptors. + UIManager = Object.create(Object.getPrototypeOf(UIManagerImpl), { + ...Object.getOwnPropertyDescriptors( + // $FlowFixMe[class-object-subtyping] UIManagerImpl is a runtime object. + UIManagerImpl, + ), + ...Object.getOwnPropertyDescriptors(UIManagerOverrides), + }); +} else { + // $FlowFixMe[cannot-spread-interface] + UIManager = { + ...UIManagerImpl, + ...UIManagerOverrides, + }; +} + export default UIManager; diff --git a/packages/react-native/Libraries/ReactNative/__tests__/UIManager-test.js b/packages/react-native/Libraries/ReactNative/__tests__/UIManager-test.js new file mode 100644 index 000000000000..273bb87bc210 --- /dev/null +++ b/packages/react-native/Libraries/ReactNative/__tests__/UIManager-test.js @@ -0,0 +1,134 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +jest.mock('../../Utilities/Platform', () => ({ + OS: 'android', + select: spec => spec.android ?? spec.native ?? spec.default, +})); +jest.unmock('../UIManager'); + +describe('UIManager', () => { + const originalBridgelessValue = global.RN$Bridgeless; + const originalUIManagerOptimization = global.RN$discordUiManagerOptimization; + const originalGetConstants = global.RN$LegacyInterop_UIManager_getConstants; + const originalGetConstantsForViewManager = + global.RN$LegacyInterop_UIManager_getConstantsForViewManager; + const originalGetDefaultEventTypes = + global.RN$LegacyInterop_UIManager_getDefaultEventTypes; + const viewManagerConfig = {Commands: {focus: 1}, NativeProps: {}}; + const getConstants = jest.fn(() => ({ + LazyViewManagersEnabled: true, + ViewManagerNames: ['RCTTestView'], + })); + const getConstantsForViewManager = jest.fn(() => viewManagerConfig); + const getDefaultEventTypes = jest.fn(() => ({})); + + beforeEach(() => { + jest.resetModules(); + getConstants.mockClear(); + getConstantsForViewManager.mockClear(); + getDefaultEventTypes.mockClear(); + + // $FlowExpectedError[cannot-write] + global.RN$Bridgeless = true; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getConstants = getConstants; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getConstantsForViewManager = + getConstantsForViewManager; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getDefaultEventTypes = + getDefaultEventTypes; + }); + + afterEach(() => { + // $FlowExpectedError[cannot-write] + global.RN$Bridgeless = originalBridgelessValue; + // $FlowExpectedError[cannot-write] + global.RN$discordUiManagerOptimization = originalUIManagerOptimization; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getConstants = originalGetConstants; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getConstantsForViewManager = + originalGetConstantsForViewManager; + // $FlowExpectedError[cannot-write] + global.RN$LegacyInterop_UIManager_getDefaultEventTypes = + originalGetDefaultEventTypes; + jest.resetModules(); + }); + + it('preserves lazy ViewManager getters in optimization mode 1', () => { + // $FlowExpectedError[cannot-write] + global.RN$discordUiManagerOptimization = 1; + + const UIManager = require('../UIManager').default; + + expect(getConstants).toHaveBeenCalledTimes(1); + expect(getConstantsForViewManager).not.toHaveBeenCalled(); + expect( + Object.getOwnPropertyDescriptor(UIManager, 'RCTTestView'), + ).toBeDefined(); + expect(Object.keys(UIManager)).toContain('RCTTestView'); + + expect(Reflect.get(UIManager, 'RCTTestView')).toBe(viewManagerConfig); + expect(Reflect.get(UIManager, 'RCTTestView')).toBe(viewManagerConfig); + expect(getConstantsForViewManager).toHaveBeenCalledTimes(1); + }); + + it('eagerly reads ViewManager getters in optimization mode 0', () => { + // $FlowExpectedError[cannot-write] + global.RN$discordUiManagerOptimization = 0; + + const UIManager = require('../UIManager').default; + + expect(getConstants).toHaveBeenCalledTimes(1); + expect(getConstantsForViewManager).toHaveBeenCalledTimes(1); + expect(Reflect.get(UIManager, 'RCTTestView')).toBe(viewManagerConfig); + }); + + it('loads and caches individual ViewManager configs on demand in optimization mode 2', () => { + // $FlowExpectedError[cannot-write] + global.RN$discordUiManagerOptimization = 2; + + const UIManager = require('../UIManager').default; + + expect(getConstants).not.toHaveBeenCalled(); + expect(getConstantsForViewManager).not.toHaveBeenCalled(); + + expect(UIManager.getViewManagerConfig('RCTTestView')).toBe( + viewManagerConfig, + ); + expect(UIManager.getViewManagerConfig('RCTTestView')).toBe( + viewManagerConfig, + ); + expect(getConstantsForViewManager).toHaveBeenCalledTimes(1); + + expect(UIManager.getConstants()).toEqual({ + LazyViewManagersEnabled: true, + ViewManagerNames: ['RCTTestView'], + }); + expect(getConstants).toHaveBeenCalledTimes(1); + }); + + it('does not load all constants when attaching default event types in optimization mode 2', () => { + // $FlowExpectedError[cannot-write] + global.RN$discordUiManagerOptimization = 2; + + const getNativeComponentAttributes = + require('../getNativeComponentAttributes').default; + getNativeComponentAttributes('RCTTestView'); + + expect(getConstants).not.toHaveBeenCalled(); + expect(getConstantsForViewManager).toHaveBeenCalledTimes(1); + expect(getDefaultEventTypes).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js b/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js index 26846a19c551..8900ebe8452a 100644 --- a/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js +++ b/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js @@ -33,6 +33,9 @@ const sizesDiffer = require('../Utilities/differ/sizesDiffer').default; const UIManager = require('./UIManager').default; const nullthrows = require('nullthrows'); +const uiManagerOptimization = global.RN$discordUiManagerOptimization ?? 0; +const shouldLoadViewManagerConstantsOnDemand = uiManagerOptimization === 2; + function getNativeComponentAttributes(uiViewClassName: string): any { const viewConfig = UIManager.getViewManagerConfig(uiViewClassName); @@ -113,6 +116,18 @@ function attachDefaultEventTypes(viewConfig: any) { // This is supported on UIManager platforms (ex: Android), // as lazy view managers are not implemented for all platforms. // See [UIManager] for details on constants and implementations. + if ( + global.RN$Bridgeless === true && + shouldLoadViewManagerConstantsOnDemand && + UIManager.getDefaultEventTypes != null + ) { + // The narrow native API avoids materializing every view manager's constants + // just to determine which default event types should be attached. + const defaultEventTypes = UIManager.getDefaultEventTypes(); + merge(viewConfig, defaultEventTypes); + return; + } + const constants = UIManager.getConstants(); if (constants.ViewManagerNames || constants.LazyViewManagersEnabled) { // Lazy view managers enabled. 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 e1828664c363..4cdc98f29d6d 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<<85428eb50bc67ecf13b7a1adb13fcffa>> + * @generated SignedSource<<652b195c21ffe47263fcfbe77a898aa1>> */ /** @@ -90,6 +90,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun disableViewPreallocationAndroid(): Boolean = accessor.disableViewPreallocationAndroid() + /** + * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. + */ + @JvmStatic + public fun discordUiManagerOptimization(): Double = accessor.discordUiManagerOptimization() + /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ 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 6b13d5a0a4da..d86c4d22365e 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<<10c483c7007076bb3c1cee1197c20c89>> */ /** @@ -30,6 +30,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var disableSubviewClippingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null + private var discordUiManagerOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null @@ -209,6 +210,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun discordUiManagerOptimization(): Double { + var cached = discordUiManagerOptimizationCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.discordUiManagerOptimization() + discordUiManagerOptimizationCache = cached + } + return cached + } + override fun enableAccessibilityOrder(): Boolean { var cached = enableAccessibilityOrderCache 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 fe79bbe1fa89..40bd79a50391 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<<1492421cd4b9bca791ee9ad5f87507a3>> */ /** @@ -48,6 +48,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun disableViewPreallocationAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun discordUiManagerOptimization(): Double + @DoNotStrip @JvmStatic public external fun enableAccessibilityOrder(): Boolean @DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): 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 344c2d8d230c..dc51cbe04a22 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<<8e8b9dacb0ff4927016bf33eaa102005>> + * @generated SignedSource<<462ac270e53d73922c29341d2bf557cc>> */ /** @@ -43,6 +43,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun disableViewPreallocationAndroid(): Boolean = false + override fun discordUiManagerOptimization(): Double = 0.0 + override fun enableAccessibilityOrder(): Boolean = false override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = true 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 fdbbe2c1c78e..2e25e6b8118f 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<<1d918610fc6dcc5a1448b2dec2234e82>> + * @generated SignedSource<> */ /** @@ -34,6 +34,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var disableSubviewClippingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null + private var discordUiManagerOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null @@ -223,6 +224,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun discordUiManagerOptimization(): Double { + var cached = discordUiManagerOptimizationCache + if (cached == null) { + cached = currentProvider.discordUiManagerOptimization() + accessedFeatureFlags.add("discordUiManagerOptimization") + discordUiManagerOptimizationCache = cached + } + return cached + } + override fun enableAccessibilityOrder(): Boolean { var cached = enableAccessibilityOrderCache 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 158836790ad4..c988df91b592 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<<6e4676a533128c0d692510669c9a69d3>> + * @generated SignedSource<> */ /** @@ -43,6 +43,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun disableViewPreallocationAndroid(): Boolean + @DoNotStrip public fun discordUiManagerOptimization(): Double + @DoNotStrip public fun enableAccessibilityOrder(): Boolean @DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): 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 bee73efa498a..26ac3a63c5dd 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<<22e430660a18eb259806cad2c5644b48>> + * @generated SignedSource<> */ /** @@ -99,6 +99,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + double discordUiManagerOptimization() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("discordUiManagerOptimization"); + return method(javaProvider_); + } + bool enableAccessibilityOrder() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAccessibilityOrder"); @@ -681,6 +687,11 @@ bool JReactNativeFeatureFlagsCxxInterop::disableViewPreallocationAndroid( return ReactNativeFeatureFlags::disableViewPreallocationAndroid(); } +double JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::discordUiManagerOptimization(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableAccessibilityOrder( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableAccessibilityOrder(); @@ -1182,6 +1193,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "disableViewPreallocationAndroid", JReactNativeFeatureFlagsCxxInterop::disableViewPreallocationAndroid), + makeNativeMethod( + "discordUiManagerOptimization", + JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization), makeNativeMethod( "enableAccessibilityOrder", JReactNativeFeatureFlagsCxxInterop::enableAccessibilityOrder), 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 e8d285ad68f3..16bd68e9c28a 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<<6caac4983daec1354baec9e589b5684e>> + * @generated SignedSource<<584ebd805c4a72383eb1e07ef28d490b>> */ /** @@ -60,6 +60,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool disableViewPreallocationAndroid( facebook::jni::alias_ref); + static double discordUiManagerOptimization( + facebook::jni::alias_ref); + static bool enableAccessibilityOrder( 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 57b3166bc9c4..16a8faf3033e 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<> + * @generated SignedSource<<8a37279e2d9a281cdeb43356993ec0a9>> */ /** @@ -66,6 +66,10 @@ bool ReactNativeFeatureFlags::disableViewPreallocationAndroid() { return getAccessor().disableViewPreallocationAndroid(); } +double ReactNativeFeatureFlags::discordUiManagerOptimization() { + return getAccessor().discordUiManagerOptimization(); +} + bool ReactNativeFeatureFlags::enableAccessibilityOrder() { return getAccessor().enableAccessibilityOrder(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 0e84e4d263ea..3c4c8d10d271 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<<01cfdab8946e251169d6a69ed712d57e>> */ /** @@ -89,6 +89,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool disableViewPreallocationAndroid(); + /** + * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. + */ + RN_EXPORT static double discordUiManagerOptimization(); + /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 720185d62521..231a308c61e1 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<<2b7dcf61f7016c4823f7d99d797e8b19>> + * @generated SignedSource<> */ /** @@ -209,6 +209,24 @@ bool ReactNativeFeatureFlagsAccessor::disableViewPreallocationAndroid() { return flagValue.value(); } +double ReactNativeFeatureFlagsAccessor::discordUiManagerOptimization() { + auto flagValue = discordUiManagerOptimization_.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(10, "discordUiManagerOptimization"); + + flagValue = currentProvider_->discordUiManagerOptimization(); + discordUiManagerOptimization_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableAccessibilityOrder() { auto flagValue = enableAccessibilityOrder_.load(); @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccessibilityOrder() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "enableAccessibilityOrder"); + markFlagAsAccessed(11, "enableAccessibilityOrder"); flagValue = currentProvider_->enableAccessibilityOrder(); enableAccessibilityOrder_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccumulatedUpdatesInRawPropsAndroid( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableAccumulatedUpdatesInRawPropsAndroid"); + markFlagAsAccessed(12, "enableAccumulatedUpdatesInRawPropsAndroid"); flagValue = currentProvider_->enableAccumulatedUpdatesInRawPropsAndroid(); enableAccumulatedUpdatesInRawPropsAndroid_ = flagValue; @@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidTextMeasurementOptimizations( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableAndroidTextMeasurementOptimizations"); + markFlagAsAccessed(13, "enableAndroidTextMeasurementOptimizations"); flagValue = currentProvider_->enableAndroidTextMeasurementOptimizations(); enableAndroidTextMeasurementOptimizations_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableBridgelessArchitecture"); + markFlagAsAccessed(14, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(15, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(16, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(17, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDifferentiatorMutationVectorPrealloc // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableDifferentiatorMutationVectorPreallocation"); + markFlagAsAccessed(18, "enableDifferentiatorMutationVectorPreallocation"); flagValue = currentProvider_->enableDifferentiatorMutationVectorPreallocation(); enableDifferentiatorMutationVectorPreallocation_ = flagValue; @@ -362,7 +380,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(18, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(19, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -380,7 +398,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(19, "enableEagerMainQueueModulesOnIOS"); + markFlagAsAccessed(20, "enableEagerMainQueueModulesOnIOS"); flagValue = currentProvider_->enableEagerMainQueueModulesOnIOS(); enableEagerMainQueueModulesOnIOS_ = flagValue; @@ -398,7 +416,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(20, "enableEagerRootViewAttachment"); + markFlagAsAccessed(21, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -416,7 +434,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(21, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(22, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -434,7 +452,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(22, "enableFabricCommitBranching"); + markFlagAsAccessed(23, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -452,7 +470,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(23, "enableFabricLogs"); + markFlagAsAccessed(24, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -470,7 +488,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(24, "enableFabricRenderer"); + markFlagAsAccessed(25, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFixForParentTagDuringReparenting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableFixForParentTagDuringReparenting"); + markFlagAsAccessed(26, "enableFixForParentTagDuringReparenting"); flagValue = currentProvider_->enableFixForParentTagDuringReparenting(); enableFixForParentTagDuringReparenting_ = 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::enableIOSExperimentalAutoFocusImplementati // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableIOSExperimentalAutoFocusImplementation"); + markFlagAsAccessed(28, "enableIOSExperimentalAutoFocusImplementation"); flagValue = currentProvider_->enableIOSExperimentalAutoFocusImplementation(); enableIOSExperimentalAutoFocusImplementation_ = flagValue; @@ -542,7 +560,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(28, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(29, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -560,7 +578,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(29, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(30, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -578,7 +596,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(30, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(31, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -596,7 +614,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(31, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(32, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -614,7 +632,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(32, "enableImperativeFocus"); + markFlagAsAccessed(33, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -632,7 +650,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(33, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(34, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -650,7 +668,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(34, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(35, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -668,7 +686,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(35, "enableKeyEvents"); + markFlagAsAccessed(36, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -686,7 +704,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(36, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(37, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -704,7 +722,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(37, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(38, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -722,7 +740,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(38, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(39, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -740,7 +758,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(39, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(40, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableMutationObserverByDefault"); + markFlagAsAccessed(41, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = 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::enableNativeViewPropTransformations() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableNativeViewPropTransformations"); + markFlagAsAccessed(43, "enableNativeViewPropTransformations"); flagValue = currentProvider_->enableNativeViewPropTransformations(); enableNativeViewPropTransformations_ = flagValue; @@ -812,7 +830,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(43, "enableNetworkEventReporting"); + markFlagAsAccessed(44, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -830,7 +848,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(44, "enablePreparedTextLayout"); + markFlagAsAccessed(45, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -848,7 +866,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(45, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(46, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSchedulerDelegateInvalidation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableSchedulerDelegateInvalidation"); + markFlagAsAccessed(47, "enableSchedulerDelegateInvalidation"); flagValue = currentProvider_->enableSchedulerDelegateInvalidation(); enableSchedulerDelegateInvalidation_ = flagValue; @@ -884,7 +902,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(47, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(48, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -902,7 +920,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(48, "enableViewCulling"); + markFlagAsAccessed(49, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -920,7 +938,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(49, "enableViewRecycling"); + markFlagAsAccessed(50, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -938,7 +956,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(50, "enableViewRecyclingForImage"); + markFlagAsAccessed(51, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -956,7 +974,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(51, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(52, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -974,7 +992,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(52, "enableViewRecyclingForText"); + markFlagAsAccessed(53, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -992,7 +1010,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(53, "enableViewRecyclingForView"); + markFlagAsAccessed(54, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -1010,7 +1028,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(54, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(55, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -1028,7 +1046,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(55, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(56, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(57, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -1064,7 +1082,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(57, "fixFindShadowNodeByTagRaceCondition"); + markFlagAsAccessed(58, "fixFindShadowNodeByTagRaceCondition"); flagValue = currentProvider_->fixFindShadowNodeByTagRaceCondition(); fixFindShadowNodeByTagRaceCondition_ = flagValue; @@ -1082,7 +1100,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(58, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(59, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(60, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1118,7 +1136,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(60, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(61, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1136,7 +1154,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(61, "fuseboxEnabledRelease"); + markFlagAsAccessed(62, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(63, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1172,7 +1190,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(63, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(64, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(65, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1208,7 +1226,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(65, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(66, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1226,7 +1244,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(66, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(67, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1244,7 +1262,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(67, "perfIssuesEnabled"); + markFlagAsAccessed(68, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1262,7 +1280,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(68, "perfMonitorV2Enabled"); + markFlagAsAccessed(69, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1280,7 +1298,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(69, "preparedTextCacheSize"); + markFlagAsAccessed(70, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1298,7 +1316,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(70, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(71, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "redBoxV2Android"); + markFlagAsAccessed(72, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "redBoxV2IOS"); + markFlagAsAccessed(73, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1352,7 +1370,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(73, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(74, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::runtimeCrashUiThreadUtils() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "runtimeCrashUiThreadUtils"); + markFlagAsAccessed(75, "runtimeCrashUiThreadUtils"); flagValue = currentProvider_->runtimeCrashUiThreadUtils(); runtimeCrashUiThreadUtils_ = flagValue; @@ -1388,7 +1406,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(75, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(76, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1406,7 +1424,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(76, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(77, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(78, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1442,7 +1460,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(78, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(79, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1460,7 +1478,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(79, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(80, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1478,7 +1496,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(80, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(81, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1496,7 +1514,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(81, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(82, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1514,7 +1532,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(82, "useFabricInterop"); + markFlagAsAccessed(83, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::useLISAlgorithmInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "useLISAlgorithmInDifferentiator"); + markFlagAsAccessed(84, "useLISAlgorithmInDifferentiator"); flagValue = currentProvider_->useLISAlgorithmInDifferentiator(); useLISAlgorithmInDifferentiator_ = flagValue; @@ -1550,7 +1568,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(84, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(85, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1568,7 +1586,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(85, "useNestedScrollViewAndroid"); + markFlagAsAccessed(86, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1586,7 +1604,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedViewRegistryOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "useOptimizedViewRegistryOnAndroid"); + markFlagAsAccessed(87, "useOptimizedViewRegistryOnAndroid"); flagValue = currentProvider_->useOptimizedViewRegistryOnAndroid(); useOptimizedViewRegistryOnAndroid_ = flagValue; @@ -1604,7 +1622,7 @@ bool ReactNativeFeatureFlagsAccessor::usePullModelOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(87, "usePullModelOnAndroid"); + markFlagAsAccessed(88, "usePullModelOnAndroid"); flagValue = currentProvider_->usePullModelOnAndroid(); usePullModelOnAndroid_ = flagValue; @@ -1622,7 +1640,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(88, "useSharedAnimatedBackend"); + markFlagAsAccessed(89, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1640,7 +1658,7 @@ bool ReactNativeFeatureFlagsAccessor::useSilenceErrorSMMViewNotFound() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(89, "useSilenceErrorSMMViewNotFound"); + markFlagAsAccessed(90, "useSilenceErrorSMMViewNotFound"); flagValue = currentProvider_->useSilenceErrorSMMViewNotFound(); useSilenceErrorSMMViewNotFound_ = flagValue; @@ -1658,7 +1676,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(90, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(91, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1676,7 +1694,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(91, "useTraitHiddenOnIOS"); + markFlagAsAccessed(92, "useTraitHiddenOnIOS"); flagValue = currentProvider_->useTraitHiddenOnIOS(); useTraitHiddenOnIOS_ = flagValue; @@ -1694,7 +1712,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(92, "useTurboModuleInterop"); + markFlagAsAccessed(93, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1712,7 +1730,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(93, "useTurboModules"); + markFlagAsAccessed(94, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1730,7 +1748,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(94, "useUnorderedMapInDifferentiator"); + markFlagAsAccessed(95, "useUnorderedMapInDifferentiator"); flagValue = currentProvider_->useUnorderedMapInDifferentiator(); useUnorderedMapInDifferentiator_ = flagValue; @@ -1748,7 +1766,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(95, "viewCullingOutsetRatio"); + markFlagAsAccessed(96, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1766,7 +1784,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(96, "viewTransitionEnabled"); + markFlagAsAccessed(97, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1784,7 +1802,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(97, "virtualViewPrerenderRatio"); + markFlagAsAccessed(98, "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 edf42f230ac6..da03826909f6 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<<7183652511b3f309064e93573cccc532>> + * @generated SignedSource<<4d3705bd5161ff7635e97ae248c74868>> */ /** @@ -42,6 +42,7 @@ class ReactNativeFeatureFlagsAccessor { bool disableSubviewClippingAndroid(); bool disableTextLayoutManagerCacheAndroid(); bool disableViewPreallocationAndroid(); + double discordUiManagerOptimization(); bool enableAccessibilityOrder(); bool enableAccumulatedUpdatesInRawPropsAndroid(); bool enableAndroidTextMeasurementOptimizations(); @@ -141,7 +142,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 98> accessedFeatureFlags_; + std::array, 99> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -153,6 +154,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> disableSubviewClippingAndroid_; std::atomic> disableTextLayoutManagerCacheAndroid_; std::atomic> disableViewPreallocationAndroid_; + std::atomic> discordUiManagerOptimization_; std::atomic> enableAccessibilityOrder_; std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; std::atomic> enableAndroidTextMeasurementOptimizations_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index b211a1b7950a..bb7a36bc0125 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<<9321638ff105b0a6eb0e2a594f579cda>> + * @generated SignedSource<> */ /** @@ -67,6 +67,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + double discordUiManagerOptimization() override { + return 0.0; + } + bool enableAccessibilityOrder() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index b45750e9a666..4d215ccd3a15 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<<1ae797d05b1fac9f396c3a5593107752>> + * @generated SignedSource<<0ce2303f050c763a34ac4998192c78af>> */ /** @@ -135,6 +135,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::disableViewPreallocationAndroid(); } + double discordUiManagerOptimization() override { + auto value = values_["discordUiManagerOptimization"]; + if (!value.isNull()) { + return value.getDouble(); + } + + return ReactNativeFeatureFlagsDefaults::discordUiManagerOptimization(); + } + bool enableAccessibilityOrder() override { auto value = values_["enableAccessibilityOrder"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 43b9b700d135..e7c2fc710792 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<> + * @generated SignedSource<<4386eff150cd9570d98c0ca4fe9a90ac>> */ /** @@ -35,6 +35,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool disableSubviewClippingAndroid() = 0; virtual bool disableTextLayoutManagerCacheAndroid() = 0; virtual bool disableViewPreallocationAndroid() = 0; + virtual double discordUiManagerOptimization() = 0; virtual bool enableAccessibilityOrder() = 0; virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; virtual bool enableAndroidTextMeasurementOptimizations() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 4c9b39d393cc..b2048a2ce519 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<<6e3d7aa0a7bbccd61549ca3e5dd26020>> */ /** @@ -94,6 +94,11 @@ bool NativeReactNativeFeatureFlags::disableViewPreallocationAndroid( return ReactNativeFeatureFlags::disableViewPreallocationAndroid(); } +double NativeReactNativeFeatureFlags::discordUiManagerOptimization( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::discordUiManagerOptimization(); +} + bool NativeReactNativeFeatureFlags::enableAccessibilityOrder( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAccessibilityOrder(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 2787ce743865..21bda15bca87 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<<5084830f5f476750cd522a526bf15055>> + * @generated SignedSource<<380250279c76aca0f139fdd0eac141db>> */ /** @@ -56,6 +56,8 @@ class NativeReactNativeFeatureFlags bool disableViewPreallocationAndroid(jsi::Runtime& runtime); + double discordUiManagerOptimization(jsi::Runtime& runtime); + bool enableAccessibilityOrder(jsi::Runtime& runtime); bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index 044d7bad5622..4591bd8dd92f 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -481,13 +481,16 @@ jsi::Value UIManagerBinding::get( auto shadowNodeList = shadowNodeListFromValue(runtime, arguments[1]); static const clock::time_point t0 = clock::now(); - const bool isWithinFirst5s = (clock::now() - t0) < std::chrono::seconds(5); + const bool isWithinFirst5s = + (clock::now() - t0) < std::chrono::seconds(5); uiManager->completeSurface( surfaceId, shadowNodeList, {.enableStateReconciliation = true, - .mountSynchronously = isWithinFirst5s, // make sure we push first render as soon as possible otherwise we observe 200ms delay + .mountSynchronously = + isWithinFirst5s, // make sure we push first render as soon as + // possible otherwise we observe 200ms delay .source = ShadowTree::CommitSource::React}); return jsi::Value::undefined(); diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 0e792803be45..6315c279de78 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -393,6 +393,17 @@ void defineReactInstanceFlags( const ReactInstance::JSRuntimeFlags& options) noexcept { defineReadOnlyGlobal(runtime, "RN$Bridgeless", jsi::Value(true)); + // Discord: inject feature flag value to global runtime object. The feature + // flag is set on the native side at app start. This way JS can read its + // value immediately. + const auto uiManagerOptimization = + ReactNativeFeatureFlags::discordUiManagerOptimization(); + auto uiManagerOptimizationValue = jsi::Value(uiManagerOptimization); + defineReadOnlyGlobal( + runtime, + "RN$discordUiManagerOptimization", + std::move(uiManagerOptimizationValue)); + if (options.isProfiling) { defineReadOnlyGlobal(runtime, "__RCTProfileIsProfiling", jsi::Value(true)); } diff --git a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp index 8d39ace3f5f7..41901726fa7d 100644 --- a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +++ b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp @@ -231,6 +231,16 @@ TEST_F(ReactInstanceTest, testBridgelessFlagIsSet) { EXPECT_EQ(val.getBool(), true); } +TEST_F(ReactInstanceTest, testUiManagerOptimizationFlagIsSetBeforeBundle) { + initializeRuntimeWithScript(R"( + globalThis.uiManagerOptimizationFlagWasDefined = + typeof RN$discordUiManagerOptimization === 'number'; + )"); + + auto val = eval("globalThis.uiManagerOptimizationFlagWasDefined"); + EXPECT_EQ(val.getBool(), true); +} + TEST_F(ReactInstanceTest, testProfilingFlag) { auto valBefore = tryEval("__RCTProfileIsProfiling === true", "false"); EXPECT_EQ(valBefore.getBool(), false); diff --git a/packages/react-native/flow/global.js b/packages/react-native/flow/global.js index dc6de666ec02..027e5a82ebf4 100644 --- a/packages/react-native/flow/global.js +++ b/packages/react-native/flow/global.js @@ -78,6 +78,7 @@ declare var global: { // Internal-specific +__DEV__?: boolean, +RN$Bridgeless?: boolean, + +RN$discordUiManagerOptimization?: number, // setupDOM +DOMRect: typeof DOMRect, diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 4732805fdf00..15646b06830a 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -158,6 +158,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + discordUiManagerOptimization: { + defaultValue: 0, + metadata: { + dateAdded: '2026-10-15', + description: + 'Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand.', + expectedReleaseValue: 2, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableAccessibilityOrder: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 1589f23a8af0..a632cb0a4eb1 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<<985615d1d3e193ee5eb60177bb7de994>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -57,6 +57,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ disableSubviewClippingAndroid: Getter, disableTextLayoutManagerCacheAndroid: Getter, disableViewPreallocationAndroid: Getter, + discordUiManagerOptimization: Getter, enableAccessibilityOrder: Getter, enableAccumulatedUpdatesInRawPropsAndroid: Getter, enableAndroidTextMeasurementOptimizations: Getter, @@ -251,6 +252,10 @@ export const disableTextLayoutManagerCacheAndroid: Getter = createNativ * Force disable view preallocation triggered from createNode off the main thread on Android */ export const disableViewPreallocationAndroid: Getter = createNativeFlagGetter('disableViewPreallocationAndroid', false); +/** + * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. + */ +export const discordUiManagerOptimization: Getter = createNativeFlagGetter('discordUiManagerOptimization', 0); /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 131a074c32e7..94154d6cd621 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<<1b452370c6697f787256c3e338702371>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -35,6 +35,7 @@ export interface Spec extends TurboModule { +disableSubviewClippingAndroid?: () => boolean; +disableTextLayoutManagerCacheAndroid?: () => boolean; +disableViewPreallocationAndroid?: () => boolean; + +discordUiManagerOptimization?: () => number; +enableAccessibilityOrder?: () => boolean; +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean; +enableAndroidTextMeasurementOptimizations?: () => boolean;