Skip to content

Commit 99cba2b

Browse files
authored
[DevTools] Build Updater List from the Commit instead of Map (#30897)
Stacked on #30896. The problem with the `getUpdatersList` function is that it iterates over Fibers and then looks up each of those Fibers in the fiberToFiberInstanceMap which we ideally could get rid of. However, every time an updater comes into play for a commit it must mean that something below the updater itself updated and so the updater will also be cloned which means we'll pass it on the way down when traversing the tree in the commit. When we do this traversal, we can just look if the Fiber is in the updater set and if so add it to the updater list as we go.
1 parent 6292398 commit 99cba2b

File tree

1 file changed

+50
-39
lines changed
  • packages/react-devtools-shared/src/backend/fiber

1 file changed

+50
-39
lines changed

packages/react-devtools-shared/src/backend/fiber/renderer.js

+50-39
Original file line numberDiff line numberDiff line change
@@ -1293,11 +1293,11 @@ export function attach(
12931293
'Expected the root instance to already exist when applying filters',
12941294
);
12951295
}
1296-
currentRootID = rootInstance.id;
1296+
currentRoot = rootInstance;
12971297
unmountInstanceRecursively(rootInstance);
12981298
rootToFiberInstanceMap.delete(root);
12991299
flushPendingEvents(root);
1300-
currentRootID = -1;
1300+
currentRoot = (null: any);
13011301
});
13021302

13031303
applyComponentFilters(componentFilters);
@@ -1323,11 +1323,11 @@ export function attach(
13231323
mightBeOnTrackedPath = true;
13241324
}
13251325

1326-
currentRootID = newRoot.id;
1327-
setRootPseudoKey(currentRootID, root.current);
1326+
currentRoot = newRoot;
1327+
setRootPseudoKey(currentRoot.id, root.current);
13281328
mountFiberRecursively(root.current, false);
13291329
flushPendingEvents(root);
1330-
currentRootID = -1;
1330+
currentRoot = (null: any);
13311331
});
13321332

13331333
// Also re-evaluate all error and warning counts given the new filters.
@@ -1528,7 +1528,7 @@ export function attach(
15281528
}
15291529

15301530
// When a mount or update is in progress, this value tracks the root that is being operated on.
1531-
let currentRootID: number = -1;
1531+
let currentRoot: FiberInstance = (null: any);
15321532

15331533
// Returns a FiberInstance if one has already been generated for the Fiber or null if one has not been generated.
15341534
// Use this method while e.g. logging to avoid over-retaining Fibers.
@@ -1885,7 +1885,12 @@ export function attach(
18851885
3 + pendingOperations.length,
18861886
);
18871887
operations[0] = rendererID;
1888-
operations[1] = currentRootID;
1888+
if (currentRoot === null) {
1889+
// TODO: This is not always safe so this field is probably not needed.
1890+
operations[1] = -1;
1891+
} else {
1892+
operations[1] = currentRoot.id;
1893+
}
18891894
operations[2] = 0; // String table size
18901895
for (let j = 0; j < pendingOperations.length; j++) {
18911896
operations[3 + j] = pendingOperations[j];
@@ -2038,7 +2043,12 @@ export function attach(
20382043
// Which in turn enables fiber props, states, and hooks to be inspected.
20392044
let i = 0;
20402045
operations[i++] = rendererID;
2041-
operations[i++] = currentRootID;
2046+
if (currentRoot === null) {
2047+
// TODO: This is not always safe so this field is probably not needed.
2048+
operations[i++] = -1;
2049+
} else {
2050+
operations[i++] = currentRoot.id;
2051+
}
20422052

20432053
// Now fill in the string table.
20442054
// [stringTableLength, str1Length, ...str1, str2Length, ...str2, ...]
@@ -2881,6 +2891,25 @@ export function attach(
28812891
}
28822892
}
28832893
}
2894+
2895+
// If this Fiber was in the set of memoizedUpdaters we need to record
2896+
// it to be included in the description of the commit.
2897+
const fiberRoot: FiberRoot = currentRoot.data.stateNode;
2898+
const updaters = fiberRoot.memoizedUpdaters;
2899+
if (
2900+
updaters != null &&
2901+
(updaters.has(fiber) ||
2902+
// We check the alternate here because we're matching identity and
2903+
// prevFiber might be same as fiber.
2904+
(fiber.alternate !== null && updaters.has(fiber.alternate)))
2905+
) {
2906+
const metadata =
2907+
((currentCommitProfilingMetadata: any): CommitProfilingData);
2908+
if (metadata.updaters === null) {
2909+
metadata.updaters = [];
2910+
}
2911+
metadata.updaters.push(instanceToSerializedElement(fiberInstance));
2912+
}
28842913
}
28852914
}
28862915

@@ -3568,8 +3597,8 @@ export function attach(
35683597
if (alternate) {
35693598
fiberToFiberInstanceMap.set(alternate, newRoot);
35703599
}
3571-
currentRootID = newRoot.id;
3572-
setRootPseudoKey(currentRootID, root.current);
3600+
currentRoot = newRoot;
3601+
setRootPseudoKey(currentRoot.id, root.current);
35733602

35743603
// Handle multi-renderer edge-case where only some v16 renderers support profiling.
35753604
if (isProfiling && rootSupportsProfiling(root)) {
@@ -3581,35 +3610,20 @@ export function attach(
35813610
commitTime: getCurrentTime() - profilingStartTime,
35823611
maxActualDuration: 0,
35833612
priorityLevel: null,
3584-
updaters: getUpdatersList(root),
3613+
updaters: null,
35853614
effectDuration: null,
35863615
passiveEffectDuration: null,
35873616
};
35883617
}
35893618

35903619
mountFiberRecursively(root.current, false);
3620+
35913621
flushPendingEvents(root);
3592-
currentRootID = -1;
3622+
currentRoot = (null: any);
35933623
});
35943624
}
35953625
}
35963626

3597-
function getUpdatersList(root: any): Array<SerializedElement> | null {
3598-
const updaters = root.memoizedUpdaters;
3599-
if (updaters == null) {
3600-
return null;
3601-
}
3602-
const result = [];
3603-
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
3604-
for (const updater of updaters) {
3605-
const inst = getFiberInstanceUnsafe(updater);
3606-
if (inst !== null) {
3607-
result.push(instanceToSerializedElement(inst));
3608-
}
3609-
}
3610-
return result;
3611-
}
3612-
36133627
function handleCommitFiberUnmount(fiber: any) {
36143628
// This Hook is no longer used. After having shipped DevTools everywhere it is
36153629
// safe to stop calling it from Fiber.
@@ -3646,11 +3660,10 @@ export function attach(
36463660
if (alternate) {
36473661
fiberToFiberInstanceMap.set(alternate, rootInstance);
36483662
}
3649-
currentRootID = rootInstance.id;
36503663
} else {
3651-
currentRootID = rootInstance.id;
36523664
prevFiber = rootInstance.data;
36533665
}
3666+
currentRoot = rootInstance;
36543667

36553668
// Before the traversals, remember to start tracking
36563669
// our path in case we have selection to restore.
@@ -3675,9 +3688,7 @@ export function attach(
36753688
maxActualDuration: 0,
36763689
priorityLevel:
36773690
priorityLevel == null ? null : formatPriorityLevel(priorityLevel),
3678-
3679-
updaters: getUpdatersList(root),
3680-
3691+
updaters: null,
36813692
// Initialize to null; if new enough React version is running,
36823693
// these values will be read during separate handlePostCommitFiberRoot() call.
36833694
effectDuration: null,
@@ -3699,28 +3710,28 @@ export function attach(
36993710
current.memoizedState.isDehydrated !== true;
37003711
if (!wasMounted && isMounted) {
37013712
// Mount a new root.
3702-
setRootPseudoKey(currentRootID, current);
3713+
setRootPseudoKey(currentRoot.id, current);
37033714
mountFiberRecursively(current, false);
37043715
} else if (wasMounted && isMounted) {
37053716
// Update an existing root.
37063717
updateFiberRecursively(rootInstance, current, prevFiber, false);
37073718
} else if (wasMounted && !isMounted) {
37083719
// Unmount an existing root.
37093720
unmountInstanceRecursively(rootInstance);
3710-
removeRootPseudoKey(currentRootID);
3721+
removeRootPseudoKey(currentRoot.id);
37113722
rootToFiberInstanceMap.delete(root);
37123723
}
37133724
} else {
37143725
// Mount a new root.
3715-
setRootPseudoKey(currentRootID, current);
3726+
setRootPseudoKey(currentRoot.id, current);
37163727
mountFiberRecursively(current, false);
37173728
}
37183729

37193730
if (isProfiling && isProfilingSupported) {
37203731
if (!shouldBailoutWithPendingOperations()) {
37213732
const commitProfilingMetadata =
37223733
((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).get(
3723-
currentRootID,
3734+
currentRoot.id,
37243735
);
37253736

37263737
if (commitProfilingMetadata != null) {
@@ -3729,7 +3740,7 @@ export function attach(
37293740
);
37303741
} else {
37313742
((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).set(
3732-
currentRootID,
3743+
currentRoot.id,
37333744
[((currentCommitProfilingMetadata: any): CommitProfilingData)],
37343745
);
37353746
}
@@ -3743,7 +3754,7 @@ export function attach(
37433754
hook.emit('traceUpdates', traceUpdatesForNodes);
37443755
}
37453756

3746-
currentRootID = -1;
3757+
currentRoot = (null: any);
37473758
}
37483759

37493760
function getResourceInstance(fiber: Fiber): HostInstance | null {

0 commit comments

Comments
 (0)