@samitouri / QOS-React / commits / 9690b9ad74

[DevTools] Remove findCurrentFiberUsingSlowPathByFiberInstance (#30818)

We always track the last committed Fiber on `FiberInstance.data`. https://github.com/facebook/react/blob/dcae56f8b72f625d8affe5729ca9991b31a492ac/packages/react-devtools-shared/src/backend/fiber/renderer.js#L3068 So we can now remove this complex slow path to get the current fiber.

Sebastian Markbåge committed Aug 27, 2024 at 12:05 UTC 9690b9ad749c30eab1900c99e7c25a7ed7e1d9b7
1 file changed +7 -214
packages/react-devtools-shared/src/backend/fiber/renderer.js
+7 -214
@@ -3550,7 +3550,7 @@ export function attach(
3550 fiberInstance: FiberInstance,
3551 ): $ReadOnlyArray<HostInstance> {
3552 const hostInstances = [];
3553 - const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance);
3553 + const fiber = fiberInstance.data;
3554 if (!fiber) {
3555 return hostInstances;
3556 }
@@ -3601,8 +3601,7 @@ export function attach(
3601 // TODO: Handle VirtualInstance.
3602 return null;
3603 }
3604 - const fiber =
3605 - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
3604 + const fiber = devtoolsInstance.data;
3605 if (fiber === null) {
3606 return null;
3607 }
@@ -3710,208 +3709,6 @@ export function attach(
3709 return null;
3710 }
3711
3713 - // This function is copied from React and should be kept in sync:
3714 - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js
3715 - function assertIsMounted(fiber: Fiber) {
3716 - if (getNearestMountedFiber(fiber) !== fiber) {
3717 - throw new Error('Unable to find node on an unmounted component.');
3718 - }
3719 - }
3720 -
3721 - // This function is copied from React and should be kept in sync:
3722 - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js
3723 - function getNearestMountedFiber(fiber: Fiber): null | Fiber {
3724 - let node = fiber;
3725 - let nearestMounted: null | Fiber = fiber;
3726 - if (!fiber.alternate) {
3727 - // If there is no alternate, this might be a new tree that isn't inserted
3728 - // yet. If it is, then it will have a pending insertion effect on it.
3729 - let nextNode: Fiber = node;
3730 - do {
3731 - node = nextNode;
3732 - // TODO: This function, and these flags, are a leaked implementation
3733 - // detail. Once we start releasing DevTools in lockstep with React, we
3734 - // should import a function from the reconciler instead.
3735 - const Placement = 0b000000000000000000000000010;
3736 - const Hydrating = 0b000000000000001000000000000;
3737 - if ((node.flags & (Placement | Hydrating)) !== 0) {
3738 - // This is an insertion or in-progress hydration. The nearest possible
3739 - // mounted fiber is the parent but we need to continue to figure out
3740 - // if that one is still mounted.
3741 - nearestMounted = node.return;
3742 - }
3743 - // $FlowFixMe[incompatible-type] we bail out when we get a null
3744 - nextNode = node.return;
3745 - } while (nextNode);
3746 - } else {
3747 - while (node.return) {
3748 - node = node.return;
3749 - }
3750 - }
3751 - if (node.tag === HostRoot) {
3752 - // TODO: Check if this was a nested HostRoot when used with
3753 - // renderContainerIntoSubtree.
3754 - return nearestMounted;
3755 - }
3756 - // If we didn't hit the root, that means that we're in an disconnected tree
3757 - // that has been unmounted.
3758 - return null;
3759 - }
3760 -
3761 - // This function is copied from React and should be kept in sync:
3762 - // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberTreeReflection.js
3763 - // It would be nice if we updated React to inject this function directly (vs just indirectly via findDOMNode).
3764 - // BEGIN copied code
3765 - function findCurrentFiberUsingSlowPathByFiberInstance(
3766 - fiberInstance: FiberInstance,
3767 - ): Fiber | null {
3768 - const fiber = fiberInstance.data;
3769 - const alternate = fiber.alternate;
3770 - if (!alternate) {
3771 - // If there is no alternate, then we only need to check if it is mounted.
3772 - const nearestMounted = getNearestMountedFiber(fiber);
3773 -
3774 - if (nearestMounted === null) {
3775 - throw new Error('Unable to find node on an unmounted component.');
3776 - }
3777 -
3778 - if (nearestMounted !== fiber) {
3779 - return null;
3780 - }
3781 - return fiber;
3782 - }
3783 - // If we have two possible branches, we'll walk backwards up to the root
3784 - // to see what path the root points to. On the way we may hit one of the
3785 - // special cases and we'll deal with them.
3786 - let a: Fiber = fiber;
3787 - let b: Fiber = alternate;
3788 - while (true) {
3789 - const parentA = a.return;
3790 - if (parentA === null) {
3791 - // We're at the root.
3792 - break;
3793 - }
3794 - const parentB = parentA.alternate;
3795 - if (parentB === null) {
3796 - // There is no alternate. This is an unusual case. Currently, it only
3797 - // happens when a Suspense component is hidden. An extra fragment fiber
3798 - // is inserted in between the Suspense fiber and its children. Skip
3799 - // over this extra fragment fiber and proceed to the next parent.
3800 - const nextParent = parentA.return;
3801 - if (nextParent !== null) {
3802 - a = b = nextParent;
3803 - continue;
3804 - }
3805 - // If there's no parent, we're at the root.
3806 - break;
3807 - }
3808 -
3809 - // If both copies of the parent fiber point to the same child, we can
3810 - // assume that the child is current. This happens when we bailout on low
3811 - // priority: the bailed out fiber's child reuses the current child.
3812 - if (parentA.child === parentB.child) {
3813 - let child = parentA.child;
3814 - while (child) {
3815 - if (child === a) {
3816 - // We've determined that A is the current branch.
3817 - assertIsMounted(parentA);
3818 - return fiber;
3819 - }
3820 - if (child === b) {
3821 - // We've determined that B is the current branch.
3822 - assertIsMounted(parentA);
3823 - return alternate;
3824 - }
3825 - child = child.sibling;
3826 - }
3827 -
3828 - // We should never have an alternate for any mounting node. So the only
3829 - // way this could possibly happen is if this was unmounted, if at all.
3830 - throw new Error('Unable to find node on an unmounted component.');
3831 - }
3832 -
3833 - if (a.return !== b.return) {
3834 - // The return pointer of A and the return pointer of B point to different
3835 - // fibers. We assume that return pointers never criss-cross, so A must
3836 - // belong to the child set of A.return, and B must belong to the child
3837 - // set of B.return.
3838 - a = parentA;
3839 - b = parentB;
3840 - } else {
3841 - // The return pointers point to the same fiber. We'll have to use the
3842 - // default, slow path: scan the child sets of each parent alternate to see
3843 - // which child belongs to which set.
3844 - //
3845 - // Search parent A's child set
3846 - let didFindChild = false;
3847 - let child = parentA.child;
3848 - while (child) {
3849 - if (child === a) {
3850 - didFindChild = true;
3851 - a = parentA;
3852 - b = parentB;
3853 - break;
3854 - }
3855 - if (child === b) {
3856 - didFindChild = true;
3857 - b = parentA;
3858 - a = parentB;
3859 - break;
3860 - }
3861 - child = child.sibling;
3862 - }
3863 - if (!didFindChild) {
3864 - // Search parent B's child set
3865 - child = parentB.child;
3866 - while (child) {
3867 - if (child === a) {
3868 - didFindChild = true;
3869 - a = parentB;
3870 - b = parentA;
3871 - break;
3872 - }
3873 - if (child === b) {
3874 - didFindChild = true;
3875 - b = parentB;
3876 - a = parentA;
3877 - break;
3878 - }
3879 - child = child.sibling;
3880 - }
3881 -
3882 - if (!didFindChild) {
3883 - throw new Error(
3884 - 'Child was not found in either parent set. This indicates a bug ' +
3885 - 'in React related to the return pointer. Please file an issue.',
3886 - );
3887 - }
3888 - }
3889 - }
3890 -
3891 - if (a.alternate !== b) {
3892 - throw new Error(
3893 - "Return fibers should always be each others' alternates. " +
3894 - 'This error is likely caused by a bug in React. Please file an issue.',
3895 - );
3896 - }
3897 - }
3898 -
3899 - // If the root is not a host container, we're in a disconnected tree. I.e.
3900 - // unmounted.
3901 - if (a.tag !== HostRoot) {
3902 - throw new Error('Unable to find node on an unmounted component.');
3903 - }
3904 -
3905 - if (a.stateNode.current === a) {
3906 - // We've determined that A is the current branch.
3907 - return fiber;
3908 - }
3909 - // Otherwise B has to be current branch.
3910 - return alternate;
3911 - }
3912 -
3913 - // END copied code
3914 -
3712 function getElementAttributeByPath(
3713 id: number,
3714 path: Array<string | number>,
@@ -4096,8 +3893,7 @@ export function attach(
3893 return {instance, style};
3894 }
3895
4099 - const fiber =
4100 - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
3896 + const fiber = devtoolsInstance.data;
3897 if (fiber !== null) {
3898 instance = fiber.stateNode;
3899
@@ -4153,7 +3949,7 @@ export function attach(
3949 function inspectFiberInstanceRaw(
3950 fiberInstance: FiberInstance,
3951 ): InspectedElement | null {
4156 - const fiber = findCurrentFiberUsingSlowPathByFiberInstance(fiberInstance);
3952 + const fiber = fiberInstance.data;
3953 if (fiber == null) {
3954 return null;
3955 }
@@ -4913,8 +4709,7 @@ export function attach(
4709 // TODO: Handle VirtualInstance.
4710 return;
4711 }
4916 - const fiber =
4917 - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
4712 + const fiber = devtoolsInstance.data;
4713 if (fiber !== null) {
4714 const instance = fiber.stateNode;
4715
@@ -4979,8 +4774,7 @@ export function attach(
4774 // TODO: Handle VirtualInstance.
4775 return;
4776 }
4982 - const fiber =
4983 - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
4777 + const fiber = devtoolsInstance.data;
4778 if (fiber !== null) {
4779 const instance = fiber.stateNode;
4780
@@ -5055,8 +4849,7 @@ export function attach(
4849 // TODO: Handle VirtualInstance.
4850 return;
4851 }
5058 - const fiber =
5059 - findCurrentFiberUsingSlowPathByFiberInstance(devtoolsInstance);
4852 + const fiber = devtoolsInstance.data;
4853 if (fiber !== null) {
4854 const instance = fiber.stateNode;
4855