@samitouri / QOS-React-1 / commits / e9638c33d7

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".

Rubén Norte committed Jul 21, 2025 at 10:27 UTC e9638c33d7e79162516b89da31549af4090997a5
11 files changed +31 -46
packages/react-native-renderer/src/ReactFiberConfigFabric.js
+10 -33
@@ -66,10 +66,7 @@ import {
66 getInspectorDataForInstance,
67 } from './ReactNativeFiberInspector';
68
69 -import {
70 - passChildrenWhenCloningPersistedNodes,
71 - enableLazyPublicInstanceInFabric,
72 -} from 'shared/ReactFeatureFlags';
69 +import {passChildrenWhenCloningPersistedNodes} from 'shared/ReactFeatureFlags';
70 import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';
71 import type {ReactContext} from 'shared/ReactTypes';
72
@@ -204,37 +201,17 @@ export function createInstance(
201 internalInstanceHandle, // internalInstanceHandle
202 );
203
207 - if (enableLazyPublicInstanceInFabric) {
208 - return {
209 - node: node,
210 - canonical: {
211 - nativeTag: tag,
212 - viewConfig,
213 - currentProps: props,
214 - internalInstanceHandle,
215 - publicInstance: null,
216 - publicRootInstance: rootContainerInstance.publicInstance,
217 - },
218 - };
219 - } else {
220 - const component = createPublicInstance(
221 - tag,
204 + return {
205 + node: node,
206 + canonical: {
207 + nativeTag: tag,
208 viewConfig,
209 + currentProps: props,
210 internalInstanceHandle,
224 - rootContainerInstance.publicInstance,
225 - );
226 -
227 - return {
228 - node: node,
229 - canonical: {
230 - nativeTag: tag,
231 - viewConfig,
232 - currentProps: props,
233 - internalInstanceHandle,
234 - publicInstance: component,
235 - },
236 - };
237 - }
211 + publicInstance: null,
212 + publicRootInstance: rootContainerInstance.publicInstance,
213 + },
214 + };
215 }
216
217 export function createTextInstance(
packages/react-native-renderer/src/ReactFiberConfigNative.js
+21 -2
@@ -15,6 +15,7 @@ import {
15 ReactNativeViewConfigRegistry,
16 UIManager,
17 deepFreezeAndThrowOnMutationInDev,
18 + createPublicInstance,
19 type PublicRootInstance,
20 } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
21
@@ -285,8 +286,26 @@ export function getChildHostContext(
286
287 export function getPublicInstance(instance: Instance): PublicInstance {
288 // $FlowExpectedError[prop-missing] For compatibility with Fabric
288 - if (instance.canonical != null && instance.canonical.publicInstance != null) {
289 - // $FlowFixMe[incompatible-return]
289 + if (instance.canonical != null) {
290 + if (instance.canonical.publicInstance == null) {
291 + // $FlowExpectedError[incompatible-use]
292 + instance.canonical.publicInstance = createPublicInstance(
293 + // $FlowExpectedError[incompatible-use]
294 + instance.canonical.nativeTag,
295 + // $FlowExpectedError[incompatible-use]
296 + instance.canonical.viewConfig,
297 + // $FlowExpectedError[incompatible-use]
298 + instance.canonical.internalInstanceHandle,
299 + // $FlowExpectedError[incompatible-use]
300 + instance.canonical.publicRootInstance ?? null,
301 + );
302 + // This was only necessary to create the public instance.
303 + // $FlowExpectedError[prop-missing]
304 + instance.canonical.publicRootInstance = null;
305 + }
306 +
307 + // $FlowExpectedError[prop-missing]
308 + // $FlowExpectedError[incompatible-return]
309 return instance.canonical.publicInstance;
310 }
311
packages/shared/ReactFeatureFlags.js
-2
@@ -151,8 +151,6 @@ export const transitionLaneExpirationMs = 5000;
151 */
152 export const enableInfiniteRenderLoopDetection = false;
153
154 -export const enableLazyPublicInstanceInFabric = false;
155 -
154 export const enableFragmentRefs = __EXPERIMENTAL__;
155
156 // -----------------------------------------------------------------------------
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
-1
@@ -23,7 +23,6 @@ export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
23 export const enablePersistedModeClonedFlag = __VARIANT__;
24 export const enableEagerAlternateStateNodeCleanup = __VARIANT__;
25 export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
26 -export const enableLazyPublicInstanceInFabric = __VARIANT__;
26 export const renameElementSymbol = __VARIANT__;
27 export const enableFragmentRefs = __VARIANT__;
28 export const enableComponentPerformanceTrack = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -25,7 +25,6 @@ export const {
25 enablePersistedModeClonedFlag,
26 enableEagerAlternateStateNodeCleanup,
27 passChildrenWhenCloningPersistedNodes,
28 - enableLazyPublicInstanceInFabric,
28 renameElementSymbol,
29 enableFragmentRefs,
30 } = dynamicFlags;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -64,7 +64,6 @@ export const enableYieldingBeforePassive = false;
64 export const enableThrottledScheduling = false;
65 export const enableViewTransition = false;
66 export const enableGestureTransition = false;
67 -export const enableLazyPublicInstanceInFabric = false;
67 export const enableScrollEndPolyfill = true;
68 export const enableSuspenseyImages = false;
69 export const enableFizzBlockingRender = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -66,7 +66,6 @@ export const enableYieldingBeforePassive = true;
66 export const enableThrottledScheduling = false;
67 export const enableViewTransition = false;
68 export const enableGestureTransition = false;
69 -export const enableLazyPublicInstanceInFabric = false;
69 export const enableScrollEndPolyfill = true;
70 export const enableSuspenseyImages = false;
71 export const enableFizzBlockingRender = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
-1
@@ -62,7 +62,6 @@ export const enableYieldingBeforePassive = false;
62 export const enableThrottledScheduling = false;
63 export const enableViewTransition = false;
64 export const enableGestureTransition = false;
65 -export const enableLazyPublicInstanceInFabric = false;
65 export const enableScrollEndPolyfill = true;
66 export const enableSuspenseyImages = false;
67 export const enableFizzBlockingRender = true;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -74,7 +74,6 @@ export const enableYieldingBeforePassive = false;
74 export const enableThrottledScheduling = false;
75 export const enableViewTransition = false;
76 export const enableGestureTransition = false;
77 -export const enableLazyPublicInstanceInFabric = false;
77 export const enableScrollEndPolyfill = true;
78 export const enableSuspenseyImages = false;
79 export const enableFizzBlockingRender = true;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -31,7 +31,6 @@ export const enableSchedulingProfiler = __VARIANT__;
31 export const enableInfiniteRenderLoopDetection = __VARIANT__;
32
33 export const enableFastAddPropertiesInDiffing = __VARIANT__;
34 -export const enableLazyPublicInstanceInFabric = false;
34 export const enableViewTransition = __VARIANT__;
35 export const enableComponentPerformanceTrack = __VARIANT__;
36 export const enableScrollEndPolyfill = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
-2
@@ -102,8 +102,6 @@ export const disableLegacyMode = true;
102
103 export const enableEagerAlternateStateNodeCleanup = true;
104
105 -export const enableLazyPublicInstanceInFabric = false;
106 -
105 export const enableGestureTransition = false;
106
107 export const enableSuspenseyImages = false;