From a5ddb07cb3d390cde3d294533cc1aaac763f0b48 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 8 Jul 2013 11:48:39 -0700 Subject: [PATCH] Make ReactMount.findComponentRoot breadth-first & non-recursive. This function needs to be as fast as possible for those cases when `ReactID.getNode` can't rely on the `nodeCache`. Breadth-first search prevents us from diving too deeply down the wrong branches when the sought-after node can be found at a shallower level. The queue required for breadth-first search is implemented by a single array indexed by `childIndex`. To save space, only the `.firstChild` nodes are stored, and we use `.nextSibling` to iterate over the other siblings in a `while` loop. --- src/core/ReactInstanceHandles.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/ReactInstanceHandles.js b/src/core/ReactInstanceHandles.js index 02ea765e0a..df3d2e8f5b 100644 --- a/src/core/ReactInstanceHandles.js +++ b/src/core/ReactInstanceHandles.js @@ -284,18 +284,30 @@ var ReactInstanceHandles = { * @internal */ findComponentRoot: function(ancestorNode, id) { - var child = ancestorNode.firstChild; - while (child) { - var childID = ReactID.getID(child); - if (childID) { - if (id === childID) { - return child; - } else if (isAncestorIDOf(childID, id)) { - return ReactInstanceHandles.findComponentRoot(child, id); + var firstChildren = [ancestorNode.firstChild]; + var childIndex = 0; + + while (childIndex < firstChildren.length) { + var child = firstChildren[childIndex++]; + while (child) { + var childID = ReactID.getID(child); + if (childID) { + if (id === childID) { + return child; + } else if (isAncestorIDOf(childID, id)) { + // If we find a child whose ID is an ancestor of the given ID, + // then we can be sure that we only want to search the subtree + // rooted at this child, so we can throw out the rest of the + // search state. + firstChildren.length = childIndex = 0; + firstChildren.push(child.firstChild); + break; + } } + child = child.nextSibling; } - child = child.nextSibling; } + global.console && console.error && console.error( 'Error while invoking `findComponentRoot` with the following ' + 'ancestor node:',