From 3cc733add482fd0f855d15ae8cbd75cc077bd674 Mon Sep 17 00:00:00 2001 From: Ben Alpert Date: Sat, 14 May 2016 12:13:48 -0700 Subject: [PATCH] Fix severe perf problems in component tree devtool (#6770) One of the ReactMultiChildText tests renders 2145 roots (and even more components) and unmounts none of them. Now we don't loop through them all a bunch of times so the test takes 20 seconds instead of 60. We should clean up instantiateReactComponent somehow so that the onSetDisplayName call isn't produced for the TopLevelWrapper, which should allow us to just store an array of unmountedIDs instead of a hash map so we at least don't have double maps. This change mirrors the old logic though. Reviewers: @gaearon, @sebmarkbage --- .../devtools/ReactComponentTreeDevtool.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/isomorphic/devtools/ReactComponentTreeDevtool.js b/src/isomorphic/devtools/ReactComponentTreeDevtool.js index 353b743e1b01e..c0347a3246e5c 100644 --- a/src/isomorphic/devtools/ReactComponentTreeDevtool.js +++ b/src/isomorphic/devtools/ReactComponentTreeDevtool.js @@ -14,7 +14,8 @@ var invariant = require('invariant'); var tree = {}; -var rootIDs = []; +var unmountedIDs = {}; +var rootIDs = {}; function updateTree(id, update) { if (!tree[id]) { @@ -28,6 +29,10 @@ function updateTree(id, update) { isMounted: false, updateCount: 0, }; + // TODO: We need to do this awkward dance because TopLevelWrapper "never + // gets mounted" but its display name gets set in instantiateReactComponent + // before its debug ID is set to 0. + unmountedIDs[id] = true; } update(tree[id]); } @@ -99,10 +104,11 @@ var ReactComponentTreeDevtool = { onMountComponent(id) { updateTree(id, item => item.isMounted = true); + delete unmountedIDs[id]; }, onMountRootComponent(id) { - rootIDs.push(id); + rootIDs[id] = true; }, onUpdateComponent(id) { @@ -111,7 +117,8 @@ var ReactComponentTreeDevtool = { onUnmountComponent(id) { updateTree(id, item => item.isMounted = false); - rootIDs = rootIDs.filter(rootID => rootID !== id); + unmountedIDs[id] = true; + delete rootIDs[id]; }, purgeUnmountedComponents() { @@ -120,9 +127,10 @@ var ReactComponentTreeDevtool = { return; } - Object.keys(tree) - .filter(id => !tree[id].isMounted) - .forEach(purgeDeep); + for (var id in unmountedIDs) { + purgeDeep(id); + } + unmountedIDs = {}; }, isMounted(id) { @@ -168,7 +176,7 @@ var ReactComponentTreeDevtool = { }, getRootIDs() { - return rootIDs; + return Object.keys(rootIDs); }, getRegisteredIDs() {