From e9638c33d7e79162516b89da31549af4090997a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Mon, 21 Jul 2025 10:27:46 +0100 Subject: [PATCH] Clean up feature flag to use lazy public instances in Fabric (#33943) ## Summary We have thoroughly tested this flag in production and proved stability and performance, so we can clean it up and "ship it". --- .../src/ReactFiberConfigFabric.js | 43 +++++-------------- .../src/ReactFiberConfigNative.js | 23 +++++++++- packages/shared/ReactFeatureFlags.js | 2 - .../ReactFeatureFlags.native-fb-dynamic.js | 1 - .../forks/ReactFeatureFlags.native-fb.js | 1 - .../forks/ReactFeatureFlags.native-oss.js | 1 - .../forks/ReactFeatureFlags.test-renderer.js | 1 - ...actFeatureFlags.test-renderer.native-fb.js | 1 - .../ReactFeatureFlags.test-renderer.www.js | 1 - .../forks/ReactFeatureFlags.www-dynamic.js | 1 - .../shared/forks/ReactFeatureFlags.www.js | 2 - 11 files changed, 31 insertions(+), 46 deletions(-) diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index f6655c0cc91af..82745e0a9979c 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -66,10 +66,7 @@ import { getInspectorDataForInstance, } from './ReactNativeFiberInspector'; -import { - passChildrenWhenCloningPersistedNodes, - enableLazyPublicInstanceInFabric, -} from 'shared/ReactFeatureFlags'; +import {passChildrenWhenCloningPersistedNodes} from 'shared/ReactFeatureFlags'; import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols'; import type {ReactContext} from 'shared/ReactTypes'; @@ -204,37 +201,17 @@ export function createInstance( internalInstanceHandle, // internalInstanceHandle ); - if (enableLazyPublicInstanceInFabric) { - return { - node: node, - canonical: { - nativeTag: tag, - viewConfig, - currentProps: props, - internalInstanceHandle, - publicInstance: null, - publicRootInstance: rootContainerInstance.publicInstance, - }, - }; - } else { - const component = createPublicInstance( - tag, + return { + node: node, + canonical: { + nativeTag: tag, viewConfig, + currentProps: props, internalInstanceHandle, - rootContainerInstance.publicInstance, - ); - - return { - node: node, - canonical: { - nativeTag: tag, - viewConfig, - currentProps: props, - internalInstanceHandle, - publicInstance: component, - }, - }; - } + publicInstance: null, + publicRootInstance: rootContainerInstance.publicInstance, + }, + }; } export function createTextInstance( diff --git a/packages/react-native-renderer/src/ReactFiberConfigNative.js b/packages/react-native-renderer/src/ReactFiberConfigNative.js index 6ff7eb3b91a3b..a4eb203b40eae 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigNative.js +++ b/packages/react-native-renderer/src/ReactFiberConfigNative.js @@ -15,6 +15,7 @@ import { ReactNativeViewConfigRegistry, UIManager, deepFreezeAndThrowOnMutationInDev, + createPublicInstance, type PublicRootInstance, } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; @@ -285,8 +286,26 @@ export function getChildHostContext( export function getPublicInstance(instance: Instance): PublicInstance { // $FlowExpectedError[prop-missing] For compatibility with Fabric - if (instance.canonical != null && instance.canonical.publicInstance != null) { - // $FlowFixMe[incompatible-return] + if (instance.canonical != null) { + if (instance.canonical.publicInstance == null) { + // $FlowExpectedError[incompatible-use] + instance.canonical.publicInstance = createPublicInstance( + // $FlowExpectedError[incompatible-use] + instance.canonical.nativeTag, + // $FlowExpectedError[incompatible-use] + instance.canonical.viewConfig, + // $FlowExpectedError[incompatible-use] + instance.canonical.internalInstanceHandle, + // $FlowExpectedError[incompatible-use] + instance.canonical.publicRootInstance ?? null, + ); + // This was only necessary to create the public instance. + // $FlowExpectedError[prop-missing] + instance.canonical.publicRootInstance = null; + } + + // $FlowExpectedError[prop-missing] + // $FlowExpectedError[incompatible-return] return instance.canonical.publicInstance; } diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 193301228ecc2..0e80e113490e5 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -151,8 +151,6 @@ export const transitionLaneExpirationMs = 5000; */ export const enableInfiniteRenderLoopDetection = false; -export const enableLazyPublicInstanceInFabric = false; - export const enableFragmentRefs = __EXPERIMENTAL__; // ----------------------------------------------------------------------------- diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js index a028ce985bd5f..f3c828b260feb 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -23,7 +23,6 @@ export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__; export const enablePersistedModeClonedFlag = __VARIANT__; export const enableEagerAlternateStateNodeCleanup = __VARIANT__; export const passChildrenWhenCloningPersistedNodes = __VARIANT__; -export const enableLazyPublicInstanceInFabric = __VARIANT__; export const renameElementSymbol = __VARIANT__; export const enableFragmentRefs = __VARIANT__; export const enableComponentPerformanceTrack = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 352afe2c88591..808bcedf8bc6b 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -25,7 +25,6 @@ export const { enablePersistedModeClonedFlag, enableEagerAlternateStateNodeCleanup, passChildrenWhenCloningPersistedNodes, - enableLazyPublicInstanceInFabric, renameElementSymbol, enableFragmentRefs, } = dynamicFlags; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index b9e29ca0ea146..6289eb438e4c9 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -64,7 +64,6 @@ export const enableYieldingBeforePassive = false; export const enableThrottledScheduling = false; export const enableViewTransition = false; export const enableGestureTransition = false; -export const enableLazyPublicInstanceInFabric = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; export const enableFizzBlockingRender = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 8d13173dfe8e2..ed7f2c81f9ef5 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -66,7 +66,6 @@ export const enableYieldingBeforePassive = true; export const enableThrottledScheduling = false; export const enableViewTransition = false; export const enableGestureTransition = false; -export const enableLazyPublicInstanceInFabric = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; export const enableFizzBlockingRender = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index 63594bac238ca..52a85eec8c61c 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -62,7 +62,6 @@ export const enableYieldingBeforePassive = false; export const enableThrottledScheduling = false; export const enableViewTransition = false; export const enableGestureTransition = false; -export const enableLazyPublicInstanceInFabric = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; export const enableFizzBlockingRender = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 449043e9fc926..ba132aebf8ddd 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -74,7 +74,6 @@ export const enableYieldingBeforePassive = false; export const enableThrottledScheduling = false; export const enableViewTransition = false; export const enableGestureTransition = false; -export const enableLazyPublicInstanceInFabric = false; export const enableScrollEndPolyfill = true; export const enableSuspenseyImages = false; export const enableFizzBlockingRender = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index db9fa0f2cb3f9..8c24986aa8259 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -31,7 +31,6 @@ export const enableSchedulingProfiler = __VARIANT__; export const enableInfiniteRenderLoopDetection = __VARIANT__; export const enableFastAddPropertiesInDiffing = __VARIANT__; -export const enableLazyPublicInstanceInFabric = false; export const enableViewTransition = __VARIANT__; export const enableComponentPerformanceTrack = __VARIANT__; export const enableScrollEndPolyfill = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 994ffc40d9ba9..e1eee10a34e07 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -102,8 +102,6 @@ export const disableLegacyMode = true; export const enableEagerAlternateStateNodeCleanup = true; -export const enableLazyPublicInstanceInFabric = false; - export const enableGestureTransition = false; export const enableSuspenseyImages = false;