@samitouri / QOS-React / commits / e0cc7202e1

[flags] Clean up `enableHiddenSubtreeInsertionEffectCleanup` (#35918)

Been enabled in stable for quite a while, also rolled out at Meta.

Ruslan Lesiutin committed Feb 27, 2026 at 14:46 UTC e0cc7202e14418b453c69c4f06dc00c64151f202
13 files changed +17 -53
packages/react-reconciler/src/ReactFiberCommitWork.js
+6 -12
@@ -48,7 +48,6 @@ import {
48 alwaysThrottleRetries,
49 enableCreateEventHandleAPI,
50 enableEffectEventMutationPhase,
51 - enableHiddenSubtreeInsertionEffectCleanup,
51 enableProfilerTimer,
52 enableProfilerCommitHooks,
53 enableSuspenseCallback,
@@ -1663,17 +1662,12 @@ function commitDeletionEffectsOnFiber(
1662 case ForwardRef:
1663 case MemoComponent:
1664 case SimpleMemoComponent: {
1666 - if (
1667 - enableHiddenSubtreeInsertionEffectCleanup ||
1668 - !offscreenSubtreeWasHidden
1669 - ) {
1670 - // TODO: Use a commitHookInsertionUnmountEffects wrapper to record timings.
1671 - commitHookEffectListUnmount(
1672 - HookInsertion,
1673 - deletedFiber,
1674 - nearestMountedAncestor,
1675 - );
1676 - }
1665 + // TODO: Use a commitHookInsertionUnmountEffects wrapper to record timings.
1666 + commitHookEffectListUnmount(
1667 + HookInsertion,
1668 + deletedFiber,
1669 + nearestMountedAncestor,
1670 + );
1671 if (!offscreenSubtreeWasHidden) {
1672 commitHookLayoutUnmountEffects(
1673 deletedFiber,
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+4 -8
@@ -3070,14 +3070,10 @@ describe('ReactHooksWithNoopRenderer', () => {
3070 await act(() => {
3071 root.render(<Activity mode="hidden" />);
3072 });
3073 - assertConsoleErrorDev(
3074 - gate('enableHiddenSubtreeInsertionEffectCleanup')
3075 - ? [
3076 - 'useInsertionEffect must not schedule updates.\n' +
3077 - ' in App (at **)',
3078 - ]
3079 - : [],
3080 - );
3073 + assertConsoleErrorDev([
3074 + 'useInsertionEffect must not schedule updates.\n' +
3075 + ' in App (at **)',
3076 + ]);
3077
3078 // Should not warn for regular effects after throw.
3079 function NotInsertion() {
packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
+4 -12
@@ -1610,9 +1610,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1610 'AsyncText:InnerAsync_1 render',
1611 'Text:OuterFallback destroy insertion',
1612 'Text:OuterFallback destroy layout',
1613 - ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
1614 - ? ['Text:InnerFallback destroy insertion']
1615 - : []),
1613 + 'Text:InnerFallback destroy insertion',
1614 'Text:Outer create layout',
1615 'AsyncText:OuterAsync_1 create layout',
1616 'Text:Inner create layout',
@@ -1757,9 +1755,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1755 assertLog([
1756 'Text:Inside render',
1757 'AsyncText:OutsideAsync render',
1760 - ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
1761 - ? ['Text:Fallback:Inside destroy insertion']
1762 - : []),
1758 + 'Text:Fallback:Inside destroy insertion',
1759 'Text:Fallback:Fallback destroy insertion',
1760 'Text:Fallback:Fallback destroy layout',
1761 'Text:Fallback:Outside destroy insertion',
@@ -2248,9 +2244,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2244
2245 // Destroy layout and passive effects in the errored tree.
2246 'App destroy layout',
2251 - ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
2252 - ? ['Text:Inside destroy insertion']
2253 - : []),
2247 + 'Text:Inside destroy insertion',
2248 'Text:Fallback destroy insertion',
2249 'Text:Fallback destroy layout',
2250 'Text:Outside destroy insertion',
@@ -2511,9 +2505,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2505
2506 // Destroy layout and passive effects in the errored tree.
2507 'App destroy layout',
2514 - ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
2515 - ? ['Text:Inside destroy insertion']
2516 - : []),
2508 + 'Text:Inside destroy insertion',
2509 'Text:Fallback destroy insertion',
2510 'Text:Fallback destroy layout',
2511 'Text:Outside destroy insertion',
packages/react-reconciler/src/__tests__/useEffectEvent-test.js
+3 -8
@@ -938,14 +938,9 @@ describe('useEffectEvent', () => {
938 assertLog([
939 'Parent Insertion Create: A 3 2',
940 'Parent Layout Cleanup: A 3 2',
941 - ...(gate('enableHiddenSubtreeInsertionEffectCleanup')
942 - ? [
943 - gate('enableViewTransition') &&
944 - !gate('enableEffectEventMutationPhase')
945 - ? 'Child Insertion Destroy A 3 2 B 1 1 1'
946 - : 'Child Insertion Destroy A 3 2 B 3 2 2',
947 - ]
948 - : []),
941 + gate('enableViewTransition') && !gate('enableEffectEventMutationPhase')
942 + ? 'Child Insertion Destroy A 3 2 B 1 1 1'
943 + : 'Child Insertion Destroy A 3 2 B 3 2 2',
944 ]);
945 });
946
packages/shared/ReactFeatureFlags.js
-5
@@ -162,11 +162,6 @@ export const enableInternalInstanceMap: boolean = false;
162
163 // const __NEXT_MAJOR__ = __EXPERIMENTAL__;
164
165 -/**
166 - * Enables a fix to run insertion effect cleanup on hidden subtrees.
167 - */
168 -export const enableHiddenSubtreeInsertionEffectCleanup: boolean = true;
169 -
165 /**
166 * Removes legacy style context defined using static `contextTypes` and consumed with static `childContextTypes`.
167 */
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
-1
@@ -19,7 +19,6 @@
19
20 export const alwaysThrottleRetries = __VARIANT__;
21 export const enableObjectFiber = __VARIANT__;
22 -export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
22 export const enableEagerAlternateStateNodeCleanup = __VARIANT__;
23 export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
24 export const enableFragmentRefs = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -21,7 +21,6 @@ const dynamicFlags: DynamicExportsType = (dynamicFlagsUntyped: any);
21 export const {
22 alwaysThrottleRetries,
23 enableEffectEventMutationPhase,
24 - enableHiddenSubtreeInsertionEffectCleanup,
24 enableObjectFiber,
25 enableEagerAlternateStateNodeCleanup,
26 passChildrenWhenCloningPersistedNodes,
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -30,7 +30,6 @@ export const enableCPUSuspense: boolean = false;
30 export const enableCreateEventHandleAPI: boolean = false;
31 export const enableMoveBefore: boolean = true;
32 export const enableFizzExternalRuntime: boolean = true;
33 -export const enableHiddenSubtreeInsertionEffectCleanup: boolean = false;
33 export const enableInfiniteRenderLoopDetection: boolean = false;
34 export const enableLegacyCache: boolean = false;
35 export const enableLegacyFBSupport: boolean = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -33,7 +33,6 @@ export const enableCPUSuspense: boolean = false;
33 export const enableNoCloningMemoCache: boolean = false;
34 export const enableLegacyFBSupport: boolean = false;
35 export const enableMoveBefore: boolean = false;
36 -export const enableHiddenSubtreeInsertionEffectCleanup: boolean = false;
36
37 export const enableRetryLaneExpiration: boolean = false;
38 export const retryLaneExpirationMs = 5000;
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
-1
@@ -26,7 +26,6 @@ export const enableCreateEventHandleAPI = false;
26 export const enableMoveBefore = false;
27 export const enableFizzExternalRuntime = true;
28 export const enableInfiniteRenderLoopDetection = false;
29 -export const enableHiddenSubtreeInsertionEffectCleanup = true;
29 export const enableLegacyCache = false;
30 export const enableLegacyFBSupport = false;
31 export const enableLegacyHidden = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -35,7 +35,6 @@ export const enableCPUSuspense: boolean = false;
35 export const enableNoCloningMemoCache: boolean = false;
36 export const enableLegacyFBSupport: boolean = false;
37 export const enableMoveBefore: boolean = false;
38 -export const enableHiddenSubtreeInsertionEffectCleanup: boolean = true;
38
39 export const enableRetryLaneExpiration: boolean = false;
40 export const retryLaneExpirationMs = 5000;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -16,7 +16,6 @@
16 export const alwaysThrottleRetries: boolean = __VARIANT__;
17 export const disableLegacyContextForFunctionComponents: boolean = __VARIANT__;
18 export const disableSchedulerTimeoutInWorkLoop: boolean = __VARIANT__;
19 -export const enableHiddenSubtreeInsertionEffectCleanup: boolean = __VARIANT__;
19 export const enableNoCloningMemoCache: boolean = __VARIANT__;
20 export const enableObjectFiber: boolean = __VARIANT__;
21 export const enableRetryLaneExpiration: boolean = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -19,7 +19,6 @@ export const {
19 disableLegacyContextForFunctionComponents,
20 disableSchedulerTimeoutInWorkLoop,
21 enableEffectEventMutationPhase,
22 - enableHiddenSubtreeInsertionEffectCleanup,
22 enableInfiniteRenderLoopDetection,
23 enableNoCloningMemoCache,
24 enableObjectFiber,