@samitouri / QOS-React-2 / commits / ce13860281

Remove enablePersistentOffscreenHostContainer flag (#24460)

This was a Fabric-related experiment that we ended up not shipping.

Andrew Clark committed Apr 28, 2022 at 15:05 UTC ce13860281f833de8a3296b7a3dad9caced102e9
24 files changed +25 -688
packages/react-native-renderer/src/ReactFabricHostConfig.js
-32
@@ -7,7 +7,6 @@
7 * @flow
8 */
9
10 -import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
10 import type {ElementRef} from 'react';
11 import type {
12 HostComponent,
@@ -545,37 +544,6 @@ export function cloneInstance(
544 };
545 }
546
548 -// TODO: These two methods should be replaced with `createOffscreenInstance` and
549 -// `cloneOffscreenInstance`. I did it this way for now because the offscreen
550 -// instance is stored on an extra HostComponent fiber instead of the
551 -// OffscreenComponent fiber, and I didn't want to add an extra check to the
552 -// generic HostComponent path. Instead we should use the OffscreenComponent
553 -// fiber, but currently Fabric expects a 1:1 correspondence between Fabric
554 -// instances and host fibers, so I'm leaving this optimization for later once
555 -// we can confirm this won't break any downstream expectations.
556 -export function getOffscreenContainerType(): string {
557 - return 'RCTView';
558 -}
559 -
560 -export function getOffscreenContainerProps(
561 - mode: OffscreenMode,
562 - children: ReactNodeList,
563 -): Props {
564 - if (mode === 'hidden') {
565 - return {
566 - children,
567 - style: {display: 'none'},
568 - };
569 - } else {
570 - return {
571 - children,
572 - style: {
573 - flex: 1,
574 - },
575 - };
576 - }
577 -}
578 -
547 export function cloneHiddenInstance(
548 instance: Instance,
549 type: string,
packages/react-noop-renderer/src/createReactNoop.js
+3 -176
@@ -19,7 +19,7 @@ import type {
19 TransitionTracingCallbacks,
20 } from 'react-reconciler/src/ReactInternalTypes';
21 import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
22 -import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
22 +import type {ReactNodeList} from 'shared/ReactTypes';
23 import type {RootTag} from 'react-reconciler/src/ReactRootTags';
24
25 import * as Scheduler from 'scheduler/unstable_mock';
@@ -595,20 +595,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
595 container.children = newChildren;
596 },
597
598 - getOffscreenContainerType(): string {
599 - return 'offscreen';
600 - },
601 -
602 - getOffscreenContainerProps(
603 - mode: OffscreenMode,
604 - children: ReactNodeList,
605 - ): Props {
606 - return {
607 - hidden: mode === 'hidden',
608 - children,
609 - };
610 - },
611 -
598 cloneHiddenInstance(
599 instance: Instance,
600 type: string,
@@ -721,9 +707,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
707
708 function getChildren(root) {
709 if (root) {
724 - return useMutation
725 - ? root.children
726 - : removeOffscreenContainersFromChildren(root.children, false);
710 + return root.children;
711 } else {
712 return null;
713 }
@@ -731,169 +715,12 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
715
716 function getPendingChildren(root) {
717 if (root) {
734 - return useMutation
735 - ? root.children
736 - : removeOffscreenContainersFromChildren(root.pendingChildren, false);
718 + return root.children;
719 } else {
720 return null;
721 }
722 }
723
742 - function removeOffscreenContainersFromChildren(children, hideNearestNode) {
743 - // Mutation mode and persistent mode have different outputs for Offscreen
744 - // and Suspense trees. Persistent mode adds an additional host node wrapper,
745 - // whereas mutation mode does not.
746 - //
747 - // This function removes the offscreen host wrappers so that the output is
748 - // consistent. If the offscreen node is hidden, it transfers the hiddenness
749 - // to the child nodes, to mimic how it works in mutation mode. That way our
750 - // tests don't have to fork tree assertions.
751 - //
752 - // So, it takes a tree that looks like this:
753 - //
754 - // <offscreen hidden={true}>
755 - // <span>A</span>
756 - // <span>B</span>
757 - // </offscren>
758 - //
759 - // And turns it into this:
760 - //
761 - // <span hidden={true}>A</span>
762 - // <span hidden={true}>B</span>
763 - //
764 - // We don't mutate the original tree, but instead return a copy.
765 - //
766 - // This function is only used by our test assertions, via the `getChildren`
767 - // and `getChildrenAsJSX` methods.
768 - let didClone = false;
769 - const newChildren = [];
770 - for (let i = 0; i < children.length; i++) {
771 - const child = children[i];
772 - const innerChildren = child.children;
773 - if (innerChildren !== undefined) {
774 - // This is a host instance instance
775 - const instance: Instance = (child: any);
776 - if (instance.type === 'offscreen') {
777 - // This is an offscreen wrapper instance. Remove it from the tree
778 - // and recursively return its children, as if it were a fragment.
779 - didClone = true;
780 - if (instance.text !== null) {
781 - // If this offscreen tree contains only text, we replace it with
782 - // a text child. Related to `shouldReplaceTextContent` feature.
783 - const offscreenTextInstance: TextInstance = {
784 - text: instance.text,
785 - id: instanceCounter++,
786 - parent: instance.parent,
787 - hidden: hideNearestNode || instance.hidden,
788 - context: instance.context,
789 - };
790 - // Hide from unit tests
791 - Object.defineProperty(offscreenTextInstance, 'id', {
792 - value: offscreenTextInstance.id,
793 - enumerable: false,
794 - });
795 - Object.defineProperty(offscreenTextInstance, 'parent', {
796 - value: offscreenTextInstance.parent,
797 - enumerable: false,
798 - });
799 - Object.defineProperty(offscreenTextInstance, 'context', {
800 - value: offscreenTextInstance.context,
801 - enumerable: false,
802 - });
803 - newChildren.push(offscreenTextInstance);
804 - } else {
805 - // Skip the offscreen node and replace it with its children
806 - const offscreenChildren = removeOffscreenContainersFromChildren(
807 - innerChildren,
808 - hideNearestNode || instance.hidden,
809 - );
810 - newChildren.push.apply(newChildren, offscreenChildren);
811 - }
812 - } else {
813 - // This is a regular (non-offscreen) instance. If the nearest
814 - // offscreen boundary is hidden, hide this node.
815 - const hidden = hideNearestNode ? true : instance.hidden;
816 - const clonedChildren = removeOffscreenContainersFromChildren(
817 - instance.children,
818 - // We never need to hide the children of this node, since if we're
819 - // inside a hidden tree, then the hidden style will be applied to
820 - // this node.
821 - false,
822 - );
823 - if (
824 - clonedChildren === instance.children &&
825 - hidden === instance.hidden
826 - ) {
827 - // No changes. Reuse the original instance without cloning.
828 - newChildren.push(instance);
829 - } else {
830 - didClone = true;
831 - const clone: Instance = {
832 - id: instance.id,
833 - type: instance.type,
834 - parent: instance.parent,
835 - children: clonedChildren,
836 - text: instance.text,
837 - prop: instance.prop,
838 - hidden: hideNearestNode ? true : instance.hidden,
839 - context: instance.context,
840 - };
841 - Object.defineProperty(clone, 'id', {
842 - value: clone.id,
843 - enumerable: false,
844 - });
845 - Object.defineProperty(clone, 'parent', {
846 - value: clone.parent,
847 - enumerable: false,
848 - });
849 - Object.defineProperty(clone, 'text', {
850 - value: clone.text,
851 - enumerable: false,
852 - });
853 - Object.defineProperty(clone, 'context', {
854 - value: clone.context,
855 - enumerable: false,
856 - });
857 - newChildren.push(clone);
858 - }
859 - }
860 - } else {
861 - // This is a text instance
862 - const textInstance: TextInstance = (child: any);
863 - if (hideNearestNode) {
864 - didClone = true;
865 - const clone = {
866 - text: textInstance.text,
867 - id: textInstance.id,
868 - parent: textInstance.parent,
869 - hidden: textInstance.hidden || hideNearestNode,
870 - context: textInstance.context,
871 - };
872 - Object.defineProperty(clone, 'id', {
873 - value: clone.id,
874 - enumerable: false,
875 - });
876 - Object.defineProperty(clone, 'parent', {
877 - value: clone.parent,
878 - enumerable: false,
879 - });
880 - Object.defineProperty(clone, 'context', {
881 - value: clone.context,
882 - enumerable: false,
883 - });
884 -
885 - newChildren.push(clone);
886 - } else {
887 - newChildren.push(textInstance);
888 - }
889 - }
890 - }
891 - // There are some tests that assume reference equality, so preserve it
892 - // when possible. Alternatively, we could update the tests to compare the
893 - // ids instead.
894 - return didClone ? newChildren : children;
895 - }
896 -
724 function getChildrenAsJSX(root) {
725 const children = childToJSX(getChildren(root), null);
726 if (children === null) {
packages/react-reconciler/src/ReactFiber.new.js
+1 -24
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
14 import type {WorkTag} from './ReactWorkTags';
15 import type {TypeOfMode} from './ReactTypeOfMode';
16 import type {Lanes} from './ReactFiberLane.new';
17 -import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17 +import type {SuspenseInstance} from './ReactFiberHostConfig';
18 import type {
19 OffscreenProps,
20 OffscreenInstance,
@@ -32,10 +32,6 @@ import {
32 enableTransitionTracing,
33 enableDebugTracing,
34 } from 'shared/ReactFeatureFlags';
35 -import {
36 - supportsPersistence,
37 - getOffscreenContainerType,
38 -} from './ReactFiberHostConfig';
35 import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
36 import {ConcurrentRoot} from './ReactRootTags';
37 import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
601 return fiber;
602 }
603
608 -export function createOffscreenHostContainerFiber(
609 - props: Props,
610 - fiberMode: TypeOfMode,
611 - lanes: Lanes,
612 - key: null | string,
613 -): Fiber {
614 - if (supportsPersistence) {
615 - const type = getOffscreenContainerType();
616 - const fiber = createFiber(HostComponent, props, key, fiberMode);
617 - fiber.elementType = type;
618 - fiber.type = type;
619 - fiber.lanes = lanes;
620 - return fiber;
621 - } else {
622 - // Only implemented in persistent mode
623 - throw new Error('Not implemented.');
624 - }
625 -}
626 -
604 export function createFiberFromElement(
605 element: ReactElement,
606 mode: TypeOfMode,
packages/react-reconciler/src/ReactFiber.old.js
+1 -24
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
14 import type {WorkTag} from './ReactWorkTags';
15 import type {TypeOfMode} from './ReactTypeOfMode';
16 import type {Lanes} from './ReactFiberLane.old';
17 -import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17 +import type {SuspenseInstance} from './ReactFiberHostConfig';
18 import type {
19 OffscreenProps,
20 OffscreenInstance,
@@ -32,10 +32,6 @@ import {
32 enableTransitionTracing,
33 enableDebugTracing,
34 } from 'shared/ReactFeatureFlags';
35 -import {
36 - supportsPersistence,
37 - getOffscreenContainerType,
38 -} from './ReactFiberHostConfig';
35 import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
36 import {ConcurrentRoot} from './ReactRootTags';
37 import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
601 return fiber;
602 }
603
608 -export function createOffscreenHostContainerFiber(
609 - props: Props,
610 - fiberMode: TypeOfMode,
611 - lanes: Lanes,
612 - key: null | string,
613 -): Fiber {
614 - if (supportsPersistence) {
615 - const type = getOffscreenContainerType();
616 - const fiber = createFiber(HostComponent, props, key, fiberMode);
617 - fiber.elementType = type;
618 - fiber.type = type;
619 - fiber.lanes = lanes;
620 - return fiber;
621 - } else {
622 - // Only implemented in persistent mode
623 - throw new Error('Not implemented.');
624 - }
625 -}
626 -
604 export function createFiberFromElement(
605 element: ReactElement,
606 mode: TypeOfMode,
packages/react-reconciler/src/ReactFiberBeginWork.new.js
+2 -107
@@ -102,7 +102,6 @@ import {
102 enableLazyContextPropagation,
103 enableSuspenseLayoutEffectSemantics,
104 enableSchedulingProfiler,
105 - enablePersistentOffscreenHostContainer,
105 enableTransitionTracing,
106 enableLegacyHidden,
107 } from 'shared/ReactFeatureFlags';
@@ -161,8 +160,6 @@ import {
160 registerSuspenseInstanceRetry,
161 supportsHydration,
162 isPrimaryRenderer,
164 - supportsPersistence,
165 - getOffscreenContainerProps,
163 } from './ReactFiberHostConfig';
164 import type {SuspenseInstance} from './ReactFiberHostConfig';
165 import {shouldError, shouldSuspend} from './ReactFiberReconciler';
@@ -226,7 +223,6 @@ import {
223 createFiberFromFragment,
224 createFiberFromOffscreen,
225 createWorkInProgress,
229 - createOffscreenHostContainerFiber,
226 isSimpleFunctionComponent,
227 } from './ReactFiber.new';
228 import {
@@ -241,7 +237,6 @@ import {setWorkInProgressVersion} from './ReactMutableSource.new';
237 import {pushCacheProvider, CacheContext} from './ReactFiberCacheComponent.new';
238 import {createCapturedValue} from './ReactCapturedValue';
239 import {createClassErrorUpdate} from './ReactFiberThrow.new';
244 -import {completeSuspendedOffscreenHostContainer} from './ReactFiberCompleteWork.new';
240 import is from 'shared/objectIs';
241 import {
242 getForksAtLevel,
@@ -800,67 +795,8 @@ function updateOffscreenComponent(
795 pushRenderLanes(workInProgress, subtreeRenderLanes);
796 }
797
803 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
804 - // In persistent mode, the offscreen children are wrapped in a host node.
805 - // TODO: Optimize this to use the OffscreenComponent fiber instead of
806 - // an extra HostComponent fiber. Need to make sure this doesn't break Fabric
807 - // or some other infra that expects a HostComponent.
808 - const isHidden =
809 - nextProps.mode === 'hidden' &&
810 - (!enableLegacyHidden || workInProgress.tag !== LegacyHiddenComponent);
811 - const offscreenContainer = reconcileOffscreenHostContainer(
812 - current,
813 - workInProgress,
814 - isHidden,
815 - nextChildren,
816 - renderLanes,
817 - );
818 - return offscreenContainer;
819 - } else {
820 - reconcileChildren(current, workInProgress, nextChildren, renderLanes);
821 - return workInProgress.child;
822 - }
823 -}
824 -
825 -function reconcileOffscreenHostContainer(
826 - currentOffscreen: Fiber | null,
827 - offscreen: Fiber,
828 - isHidden: boolean,
829 - children: any,
830 - renderLanes: Lanes,
831 -) {
832 - const containerProps = getOffscreenContainerProps(
833 - isHidden ? 'hidden' : 'visible',
834 - children,
835 - );
836 - let hostContainer;
837 - if (currentOffscreen === null) {
838 - hostContainer = createOffscreenHostContainerFiber(
839 - containerProps,
840 - offscreen.mode,
841 - renderLanes,
842 - null,
843 - );
844 - } else {
845 - const currentHostContainer = currentOffscreen.child;
846 - if (currentHostContainer === null) {
847 - hostContainer = createOffscreenHostContainerFiber(
848 - containerProps,
849 - offscreen.mode,
850 - renderLanes,
851 - null,
852 - );
853 - hostContainer.flags |= Placement;
854 - } else {
855 - hostContainer = createWorkInProgress(
856 - currentHostContainer,
857 - containerProps,
858 - );
859 - }
860 - }
861 - hostContainer.return = offscreen;
862 - offscreen.child = hostContainer;
863 - return hostContainer;
798 + reconcileChildren(current, workInProgress, nextChildren, renderLanes);
799 + return workInProgress.child;
800 }
801
802 // Note: These happen to have identical begin phases, for now. We shouldn't hold
@@ -2575,24 +2511,6 @@ function updateSuspenseFallbackChildren(
2511 currentPrimaryChildFragment.treeBaseDuration;
2512 }
2513
2578 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2579 - // In persistent mode, the offscreen children are wrapped in a host node.
2580 - // We need to complete it now, because we're going to skip over its normal
2581 - // complete phase and go straight to rendering the fallback.
2582 - const currentOffscreenContainer = currentPrimaryChildFragment.child;
2583 - const offscreenContainer: Fiber = (primaryChildFragment.child: any);
2584 - const containerProps = getOffscreenContainerProps(
2585 - 'hidden',
2586 - primaryChildren,
2587 - );
2588 - offscreenContainer.pendingProps = containerProps;
2589 - offscreenContainer.memoizedProps = containerProps;
2590 - completeSuspendedOffscreenHostContainer(
2591 - currentOffscreenContainer,
2592 - offscreenContainer,
2593 - );
2594 - }
2595 -
2514 // The fallback fiber was added as a deletion during the first pass.
2515 // However, since we're going to remain on the fallback, we no longer want
2516 // to delete it.
@@ -2602,29 +2520,6 @@ function updateSuspenseFallbackChildren(
2520 currentPrimaryChildFragment,
2521 primaryChildProps,
2522 );
2605 -
2606 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2607 - // In persistent mode, the offscreen children are wrapped in a host node.
2608 - // We need to complete it now, because we're going to skip over its normal
2609 - // complete phase and go straight to rendering the fallback.
2610 - const currentOffscreenContainer = currentPrimaryChildFragment.child;
2611 - if (currentOffscreenContainer !== null) {
2612 - const isHidden = true;
2613 - const offscreenContainer = reconcileOffscreenHostContainer(
2614 - currentPrimaryChildFragment,
2615 - primaryChildFragment,
2616 - isHidden,
2617 - primaryChildren,
2618 - renderLanes,
2619 - );
2620 - offscreenContainer.memoizedProps = offscreenContainer.pendingProps;
2621 - completeSuspendedOffscreenHostContainer(
2622 - currentOffscreenContainer,
2623 - offscreenContainer,
2624 - );
2625 - }
2626 - }
2627 -
2523 // Since we're reusing a current tree, we need to reuse the flags, too.
2524 // (We don't do this in legacy mode, because in legacy mode we don't re-use
2525 // the current tree; see previous branch.)
packages/react-reconciler/src/ReactFiberBeginWork.old.js
+2 -107
@@ -102,7 +102,6 @@ import {
102 enableLazyContextPropagation,
103 enableSuspenseLayoutEffectSemantics,
104 enableSchedulingProfiler,
105 - enablePersistentOffscreenHostContainer,
105 enableTransitionTracing,
106 enableLegacyHidden,
107 } from 'shared/ReactFeatureFlags';
@@ -161,8 +160,6 @@ import {
160 registerSuspenseInstanceRetry,
161 supportsHydration,
162 isPrimaryRenderer,
164 - supportsPersistence,
165 - getOffscreenContainerProps,
163 } from './ReactFiberHostConfig';
164 import type {SuspenseInstance} from './ReactFiberHostConfig';
165 import {shouldError, shouldSuspend} from './ReactFiberReconciler';
@@ -226,7 +223,6 @@ import {
223 createFiberFromFragment,
224 createFiberFromOffscreen,
225 createWorkInProgress,
229 - createOffscreenHostContainerFiber,
226 isSimpleFunctionComponent,
227 } from './ReactFiber.old';
228 import {
@@ -241,7 +237,6 @@ import {setWorkInProgressVersion} from './ReactMutableSource.old';
237 import {pushCacheProvider, CacheContext} from './ReactFiberCacheComponent.old';
238 import {createCapturedValue} from './ReactCapturedValue';
239 import {createClassErrorUpdate} from './ReactFiberThrow.old';
244 -import {completeSuspendedOffscreenHostContainer} from './ReactFiberCompleteWork.old';
240 import is from 'shared/objectIs';
241 import {
242 getForksAtLevel,
@@ -800,67 +795,8 @@ function updateOffscreenComponent(
795 pushRenderLanes(workInProgress, subtreeRenderLanes);
796 }
797
803 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
804 - // In persistent mode, the offscreen children are wrapped in a host node.
805 - // TODO: Optimize this to use the OffscreenComponent fiber instead of
806 - // an extra HostComponent fiber. Need to make sure this doesn't break Fabric
807 - // or some other infra that expects a HostComponent.
808 - const isHidden =
809 - nextProps.mode === 'hidden' &&
810 - (!enableLegacyHidden || workInProgress.tag !== LegacyHiddenComponent);
811 - const offscreenContainer = reconcileOffscreenHostContainer(
812 - current,
813 - workInProgress,
814 - isHidden,
815 - nextChildren,
816 - renderLanes,
817 - );
818 - return offscreenContainer;
819 - } else {
820 - reconcileChildren(current, workInProgress, nextChildren, renderLanes);
821 - return workInProgress.child;
822 - }
823 -}
824 -
825 -function reconcileOffscreenHostContainer(
826 - currentOffscreen: Fiber | null,
827 - offscreen: Fiber,
828 - isHidden: boolean,
829 - children: any,
830 - renderLanes: Lanes,
831 -) {
832 - const containerProps = getOffscreenContainerProps(
833 - isHidden ? 'hidden' : 'visible',
834 - children,
835 - );
836 - let hostContainer;
837 - if (currentOffscreen === null) {
838 - hostContainer = createOffscreenHostContainerFiber(
839 - containerProps,
840 - offscreen.mode,
841 - renderLanes,
842 - null,
843 - );
844 - } else {
845 - const currentHostContainer = currentOffscreen.child;
846 - if (currentHostContainer === null) {
847 - hostContainer = createOffscreenHostContainerFiber(
848 - containerProps,
849 - offscreen.mode,
850 - renderLanes,
851 - null,
852 - );
853 - hostContainer.flags |= Placement;
854 - } else {
855 - hostContainer = createWorkInProgress(
856 - currentHostContainer,
857 - containerProps,
858 - );
859 - }
860 - }
861 - hostContainer.return = offscreen;
862 - offscreen.child = hostContainer;
863 - return hostContainer;
798 + reconcileChildren(current, workInProgress, nextChildren, renderLanes);
799 + return workInProgress.child;
800 }
801
802 // Note: These happen to have identical begin phases, for now. We shouldn't hold
@@ -2575,24 +2511,6 @@ function updateSuspenseFallbackChildren(
2511 currentPrimaryChildFragment.treeBaseDuration;
2512 }
2513
2578 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2579 - // In persistent mode, the offscreen children are wrapped in a host node.
2580 - // We need to complete it now, because we're going to skip over its normal
2581 - // complete phase and go straight to rendering the fallback.
2582 - const currentOffscreenContainer = currentPrimaryChildFragment.child;
2583 - const offscreenContainer: Fiber = (primaryChildFragment.child: any);
2584 - const containerProps = getOffscreenContainerProps(
2585 - 'hidden',
2586 - primaryChildren,
2587 - );
2588 - offscreenContainer.pendingProps = containerProps;
2589 - offscreenContainer.memoizedProps = containerProps;
2590 - completeSuspendedOffscreenHostContainer(
2591 - currentOffscreenContainer,
2592 - offscreenContainer,
2593 - );
2594 - }
2595 -
2514 // The fallback fiber was added as a deletion during the first pass.
2515 // However, since we're going to remain on the fallback, we no longer want
2516 // to delete it.
@@ -2602,29 +2520,6 @@ function updateSuspenseFallbackChildren(
2520 currentPrimaryChildFragment,
2521 primaryChildProps,
2522 );
2605 -
2606 - if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2607 - // In persistent mode, the offscreen children are wrapped in a host node.
2608 - // We need to complete it now, because we're going to skip over its normal
2609 - // complete phase and go straight to rendering the fallback.
2610 - const currentOffscreenContainer = currentPrimaryChildFragment.child;
2611 - if (currentOffscreenContainer !== null) {
2612 - const isHidden = true;
2613 - const offscreenContainer = reconcileOffscreenHostContainer(
2614 - currentPrimaryChildFragment,
2615 - primaryChildFragment,
2616 - isHidden,
2617 - primaryChildren,
2618 - renderLanes,
2619 - );
2620 - offscreenContainer.memoizedProps = offscreenContainer.pendingProps;
2621 - completeSuspendedOffscreenHostContainer(
2622 - currentOffscreenContainer,
2623 - offscreenContainer,
2624 - );
2625 - }
2626 - }
2627 -
2523 // Since we're reusing a current tree, we need to reuse the flags, too.
2524 // (We don't do this in legacy mode, because in legacy mode we don't re-use
2525 // the current tree; see previous branch.)
packages/react-reconciler/src/ReactFiberCompleteWork.new.js
+2 -70
@@ -141,7 +141,6 @@ import {
141 enableProfilerTimer,
142 enableCache,
143 enableSuspenseLayoutEffectSemantics,
144 - enablePersistentOffscreenHostContainer,
144 enableTransitionTracing,
145 } from 'shared/ReactFeatureFlags';
146 import {
@@ -347,11 +346,7 @@ if (supportsMutation) {
346 if (child !== null) {
347 child.return = node;
348 }
350 - if (enablePersistentOffscreenHostContainer) {
351 - appendAllChildren(parent, node, false, false);
352 - } else {
353 - appendAllChildren(parent, node, true, true);
354 - }
349 + appendAllChildren(parent, node, true, true);
350 } else if (node.child !== null) {
351 node.child.return = node;
352 node = node.child;
@@ -416,11 +411,7 @@ if (supportsMutation) {
411 if (child !== null) {
412 child.return = node;
413 }
419 - if (enablePersistentOffscreenHostContainer) {
420 - appendAllChildrenToContainer(containerChildSet, node, false, false);
421 - } else {
422 - appendAllChildrenToContainer(containerChildSet, node, true, true);
423 - }
414 + appendAllChildrenToContainer(containerChildSet, node, true, true);
415 } else if (node.child !== null) {
416 node.child.return = node;
417 node = node.child;
@@ -768,65 +759,6 @@ function bubbleProperties(completedWork: Fiber) {
759 return didBailout;
760 }
761
771 -export function completeSuspendedOffscreenHostContainer(
772 - current: Fiber | null,
773 - workInProgress: Fiber,
774 -) {
775 - // This is a fork of the complete phase for HostComponent. We use it when
776 - // a suspense tree is in its fallback state, because in that case the primary
777 - // tree that includes the offscreen boundary is skipped over without a
778 - // regular complete phase.
779 - //
780 - // We can optimize this path further by inlining the update logic for
781 - // offscreen instances specifically, i.e. skipping the `prepareUpdate` call.
782 - const rootContainerInstance = getRootHostContainer();
783 - const type = workInProgress.type;
784 - const newProps = workInProgress.memoizedProps;
785 - if (current !== null) {
786 - updateHostComponent(
787 - current,
788 - workInProgress,
789 - type,
790 - newProps,
791 - rootContainerInstance,
792 - );
793 - } else {
794 - const currentHostContext = getHostContext();
795 - const instance = createInstance(
796 - type,
797 - newProps,
798 - rootContainerInstance,
799 - currentHostContext,
800 - workInProgress,
801 - );
802 -
803 - appendAllChildren(instance, workInProgress, false, false);
804 -
805 - workInProgress.stateNode = instance;
806 -
807 - // Certain renderers require commit-time effects for initial mount.
808 - // (eg DOM renderer supports auto-focus for certain elements).
809 - // Make sure such renderers get scheduled for later work.
810 - if (
811 - finalizeInitialChildren(
812 - instance,
813 - type,
814 - newProps,
815 - rootContainerInstance,
816 - currentHostContext,
817 - )
818 - ) {
819 - markUpdate(workInProgress);
820 - }
821 -
822 - if (workInProgress.ref !== null) {
823 - // If there is a ref on a host node we need to schedule a callback
824 - markRef(workInProgress);
825 - }
826 - }
827 - bubbleProperties(workInProgress);
828 -}
829 -
762 function completeWork(
763 current: Fiber | null,
764 workInProgress: Fiber,
packages/react-reconciler/src/ReactFiberCompleteWork.old.js
+2 -70
@@ -141,7 +141,6 @@ import {
141 enableProfilerTimer,
142 enableCache,
143 enableSuspenseLayoutEffectSemantics,
144 - enablePersistentOffscreenHostContainer,
144 enableTransitionTracing,
145 } from 'shared/ReactFeatureFlags';
146 import {
@@ -347,11 +346,7 @@ if (supportsMutation) {
346 if (child !== null) {
347 child.return = node;
348 }
350 - if (enablePersistentOffscreenHostContainer) {
351 - appendAllChildren(parent, node, false, false);
352 - } else {
353 - appendAllChildren(parent, node, true, true);
354 - }
349 + appendAllChildren(parent, node, true, true);
350 } else if (node.child !== null) {
351 node.child.return = node;
352 node = node.child;
@@ -416,11 +411,7 @@ if (supportsMutation) {
411 if (child !== null) {
412 child.return = node;
413 }
419 - if (enablePersistentOffscreenHostContainer) {
420 - appendAllChildrenToContainer(containerChildSet, node, false, false);
421 - } else {
422 - appendAllChildrenToContainer(containerChildSet, node, true, true);
423 - }
414 + appendAllChildrenToContainer(containerChildSet, node, true, true);
415 } else if (node.child !== null) {
416 node.child.return = node;
417 node = node.child;
@@ -768,65 +759,6 @@ function bubbleProperties(completedWork: Fiber) {
759 return didBailout;
760 }
761
771 -export function completeSuspendedOffscreenHostContainer(
772 - current: Fiber | null,
773 - workInProgress: Fiber,
774 -) {
775 - // This is a fork of the complete phase for HostComponent. We use it when
776 - // a suspense tree is in its fallback state, because in that case the primary
777 - // tree that includes the offscreen boundary is skipped over without a
778 - // regular complete phase.
779 - //
780 - // We can optimize this path further by inlining the update logic for
781 - // offscreen instances specifically, i.e. skipping the `prepareUpdate` call.
782 - const rootContainerInstance = getRootHostContainer();
783 - const type = workInProgress.type;
784 - const newProps = workInProgress.memoizedProps;
785 - if (current !== null) {
786 - updateHostComponent(
787 - current,
788 - workInProgress,
789 - type,
790 - newProps,
791 - rootContainerInstance,
792 - );
793 - } else {
794 - const currentHostContext = getHostContext();
795 - const instance = createInstance(
796 - type,
797 - newProps,
798 - rootContainerInstance,
799 - currentHostContext,
800 - workInProgress,
801 - );
802 -
803 - appendAllChildren(instance, workInProgress, false, false);
804 -
805 - workInProgress.stateNode = instance;
806 -
807 - // Certain renderers require commit-time effects for initial mount.
808 - // (eg DOM renderer supports auto-focus for certain elements).
809 - // Make sure such renderers get scheduled for later work.
810 - if (
811 - finalizeInitialChildren(
812 - instance,
813 - type,
814 - newProps,
815 - rootContainerInstance,
816 - currentHostContext,
817 - )
818 - ) {
819 - markUpdate(workInProgress);
820 - }
821 -
822 - if (workInProgress.ref !== null) {
823 - // If there is a ref on a host node we need to schedule a callback
824 - markRef(workInProgress);
825 - }
826 - }
827 - bubbleProperties(workInProgress);
828 -}
829 -
762 function completeWork(
763 current: Fiber | null,
764 workInProgress: Fiber,
packages/react-reconciler/src/ReactFiberHostConfigWithNoPersistence.js
-2
@@ -25,7 +25,5 @@ export const createContainerChildSet = shim;
25 export const appendChildToContainerChildSet = shim;
26 export const finalizeContainerChildren = shim;
27 export const replaceContainerChildren = shim;
28 -export const getOffscreenContainerType = shim;
29 -export const getOffscreenContainerProps = shim;
28 export const cloneHiddenInstance = shim;
29 export const cloneHiddenTextInstance = shim;
packages/react-reconciler/src/ReactFiberThrow.new.js
-25
@@ -34,17 +34,12 @@ import {
34 ForceUpdateForLegacySuspense,
35 ForceClientRender,
36 } from './ReactFiberFlags';
37 -import {
38 - supportsPersistence,
39 - getOffscreenContainerProps,
40 -} from './ReactFiberHostConfig';
37 import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.new';
38 import {NoMode, ConcurrentMode, DebugTracingMode} from './ReactTypeOfMode';
39 import {
40 enableDebugTracing,
41 enableLazyContextPropagation,
42 enableUpdaterTracking,
47 - enablePersistentOffscreenHostContainer,
43 } from 'shared/ReactFeatureFlags';
44 import {createCapturedValue} from './ReactCapturedValue';
45 import {
@@ -336,26 +331,6 @@ function markSuspenseBoundaryShouldCapture(
331 // all lifecycle effect tags.
332 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
333
339 - if (supportsPersistence && enablePersistentOffscreenHostContainer) {
340 - // Another legacy Suspense quirk. In persistent mode, if this is the
341 - // initial mount, override the props of the host container to hide
342 - // its contents.
343 - const currentSuspenseBoundary = suspenseBoundary.alternate;
344 - if (currentSuspenseBoundary === null) {
345 - const offscreenFiber: Fiber = (suspenseBoundary.child: any);
346 - const offscreenContainer = offscreenFiber.child;
347 - if (offscreenContainer !== null) {
348 - const children = offscreenContainer.memoizedProps.children;
349 - const containerProps = getOffscreenContainerProps(
350 - 'hidden',
351 - children,
352 - );
353 - offscreenContainer.pendingProps = containerProps;
354 - offscreenContainer.memoizedProps = containerProps;
355 - }
356 - }
357 - }
358 -
334 if (sourceFiber.tag === ClassComponent) {
335 const currentSourceFiber = sourceFiber.alternate;
336 if (currentSourceFiber === null) {
packages/react-reconciler/src/ReactFiberThrow.old.js
-25
@@ -34,17 +34,12 @@ import {
34 ForceUpdateForLegacySuspense,
35 ForceClientRender,
36 } from './ReactFiberFlags';
37 -import {
38 - supportsPersistence,
39 - getOffscreenContainerProps,
40 -} from './ReactFiberHostConfig';
37 import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.old';
38 import {NoMode, ConcurrentMode, DebugTracingMode} from './ReactTypeOfMode';
39 import {
40 enableDebugTracing,
41 enableLazyContextPropagation,
42 enableUpdaterTracking,
47 - enablePersistentOffscreenHostContainer,
43 } from 'shared/ReactFeatureFlags';
44 import {createCapturedValue} from './ReactCapturedValue';
45 import {
@@ -336,26 +331,6 @@ function markSuspenseBoundaryShouldCapture(
331 // all lifecycle effect tags.
332 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
333
339 - if (supportsPersistence && enablePersistentOffscreenHostContainer) {
340 - // Another legacy Suspense quirk. In persistent mode, if this is the
341 - // initial mount, override the props of the host container to hide
342 - // its contents.
343 - const currentSuspenseBoundary = suspenseBoundary.alternate;
344 - if (currentSuspenseBoundary === null) {
345 - const offscreenFiber: Fiber = (suspenseBoundary.child: any);
346 - const offscreenContainer = offscreenFiber.child;
347 - if (offscreenContainer !== null) {
348 - const children = offscreenContainer.memoizedProps.children;
349 - const containerProps = getOffscreenContainerProps(
350 - 'hidden',
351 - children,
352 - );
353 - offscreenContainer.pendingProps = containerProps;
354 - offscreenContainer.memoizedProps = containerProps;
355 - }
356 - }
357 - }
358 -
334 if (sourceFiber.tag === ClassComponent) {
335 const currentSourceFiber = sourceFiber.alternate;
336 if (currentSourceFiber === null) {
packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
-4
@@ -121,10 +121,6 @@ export const appendChildToContainerChildSet =
121 export const finalizeContainerChildren =
122 $$$hostConfig.finalizeContainerChildren;
123 export const replaceContainerChildren = $$$hostConfig.replaceContainerChildren;
124 -export const getOffscreenContainerType =
125 - $$$hostConfig.getOffscreenContainerType;
126 -export const getOffscreenContainerProps =
127 - $$$hostConfig.getOffscreenContainerProps;
124 export const cloneHiddenInstance = $$$hostConfig.cloneHiddenInstance;
125 export const cloneHiddenTextInstance = $$$hostConfig.cloneHiddenTextInstance;
126
packages/shared/ReactFeatureFlags.js
-1
@@ -16,7 +16,6 @@
16 export const warnAboutDeprecatedLifecycles = true;
17 export const enableComponentStackLocations = true;
18 export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
19 -export const enablePersistentOffscreenHostContainer = false;
19
20 // -----------------------------------------------------------------------------
21 // Land or remove (moderate effort)
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
+9 -9
@@ -7,8 +7,10 @@
7 * @flow strict
8 */
9
10 -import typeof * as ExportsType from './ReactFeatureFlags.native-fb-dynamic';
11 -import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
10 +// NOTE: There are no flags, currently. Uncomment the stuff below if we add one.
11 +
12 +// import typeof * as ExportsType from './ReactFeatureFlags.native-fb-dynamic';
13 +// import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
14
15 // In xplat, these flags are controlled by GKs. Because most GKs have some
16 // population running in either mode, we should run our tests that way, too,
@@ -20,10 +22,8 @@ import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
22 // flag here but it won't be set to `true` in any of our test runs. Need to
23 // update the test configuration.
24
23 -export const enablePersistentOffscreenHostContainer = __VARIANT__;
24 -
25 -// Flow magic to verify the exports of this file match the original version.
26 -// eslint-disable-next-line no-unused-vars
27 -type Check<_X, Y: _X, X: Y = _X> = null;
28 -// eslint-disable-next-line no-unused-expressions
29 -(null: Check<ExportsType, DynamicFlagsType>);
25 +// // Flow magic to verify the exports of this file match the original version.
26 +// // eslint-disable-next-line no-unused-vars
27 +// type Check<_X, Y: _X, X: Y = _X> = null;
28 +// // eslint-disable-next-line no-unused-expressions
29 +// (null: Check<ExportsType, DynamicFlagsType>);
packages/shared/forks/ReactFeatureFlags.native-fb.js
+3 -2
@@ -10,13 +10,14 @@
10 import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11 import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
12
13 +// NOTE: There are no flags, currently. Uncomment the stuff below if we add one.
14 // Re-export dynamic flags from the internal module. Intentionally using *
15 // because this import is compiled to a `require` call.
15 -import * as dynamicFlags from 'ReactNativeInternalFeatureFlags';
16 +// import * as dynamicFlags from 'ReactNativeInternalFeatureFlags';
17
18 // We destructure each value before re-exporting to avoid a dynamic look-up on
19 // the exports object every time a flag is read.
19 -export const {enablePersistentOffscreenHostContainer} = dynamicFlags;
20 +// export const {} = dynamicFlags;
21
22 // The rest of the flags are static for better dead code elimination.
23 export const enableDebugTracing = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62 export const enableLegacyHidden = false;
63 export const enableSyncDefaultUpdates = true;
64 export const allowConcurrentByDefault = false;
65 -export const enablePersistentOffscreenHostContainer = false;
65 export const enableCustomElementPropertySupport = false;
66
67 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62 export const enableLegacyHidden = false;
63 export const enableSyncDefaultUpdates = true;
64 export const allowConcurrentByDefault = false;
65 -export const enablePersistentOffscreenHostContainer = false;
65 export const enableCustomElementPropertySupport = false;
66
67 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
-1
@@ -61,7 +61,6 @@ export const enableLazyContextPropagation = false;
61 export const enableLegacyHidden = false;
62 export const enableSyncDefaultUpdates = true;
63 export const allowConcurrentByDefault = true;
64 -export const enablePersistentOffscreenHostContainer = false;
64
65 export const consoleManagedByDevToolsDuringStrictMode = false;
66 export const enableServerContext = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62 export const enableLegacyHidden = false;
63 export const enableSyncDefaultUpdates = true;
64 export const allowConcurrentByDefault = true;
65 -export const enablePersistentOffscreenHostContainer = false;
65 export const enableCustomElementPropertySupport = false;
66
67 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.testing.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62 export const enableLegacyHidden = false;
63 export const enableSyncDefaultUpdates = true;
64 export const allowConcurrentByDefault = false;
65 -export const enablePersistentOffscreenHostContainer = false;
65 export const enableCustomElementPropertySupport = false;
66
67 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62 export const enableLegacyHidden = false;
63 export const enableSyncDefaultUpdates = true;
64 export const allowConcurrentByDefault = true;
65 -export const enablePersistentOffscreenHostContainer = false;
65 export const enableCustomElementPropertySupport = false;
66
67 export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -60,6 +60,5 @@ export const disableNativeComponentFrames = false;
60 export const createRootStrictEffectsByDefault = false;
61 export const enableStrictEffects = false;
62 export const allowConcurrentByDefault = true;
63 -export const enablePersistentOffscreenHostContainer = false;
63 // You probably *don't* want to add more hardcoded ones.
64 // Instead, try to add them above with the __VARIANT__ value.
packages/shared/forks/ReactFeatureFlags.www.js
-2
@@ -99,8 +99,6 @@ export const allowConcurrentByDefault = true;
99
100 export const deletedTreeCleanUpLevel = 3;
101
102 -export const enablePersistentOffscreenHostContainer = false;
103 -
102 export const consoleManagedByDevToolsDuringStrictMode = true;
103 export const enableServerContext = true;
104
scripts/flow/xplat.js
-1
@@ -8,5 +8,4 @@
8 */
9
10 declare module 'ReactNativeInternalFeatureFlags' {
11 - declare export var enablePersistentOffscreenHostContainer: boolean;
11 }