Finding the Deepest Node on a Page
React component structures are sometimes deceivingly complex. (Shameless plug alert!) While making my portfolio, I looked at App.js and it seems very small and simple. But in actuality, going to any one of the imported components reveals a deep structure of JSX. So then I had a thought — could I write a function to find the deepest node on a page? By deepest I mean the node on which we’d have to call .parentNode the greatest number of times until we get to <body>.
I did that.
function deepestNode() {
function depthFromBody(node) {
if (node.closest('body')) {
let body = document.querySelector('body')
let parent = node
let dist = 0 while (parent !== body) {
parent = parent.parentNode
dist++
} return dist
} else {
return -1
}
} const allNodes = [...document.querySelectorAll('*')] let deepestNode = null
let deepestNodeDepth = 0 allNodes.forEach(node => {
let nodeDepth = depthFromBody(node) if (nodeDepth > deepestNodeDepth) {
deepestNode = node
deepestNodeDepth = nodeDepth
}
}) return [deepestNode, deepestNodeDepth]
}
But this is relatively inefficient. We are executing a while loop for each node on the page. If that doesn’t seem like there are that many nodes, go ahead and execute document.querySelectorAll(‘*’).length in the dev tools console. Depending on how deep the average node is, each while loop could be 10 iterations or more.
In other words, if we have something like:
...
<grandparent>
<parent>
<child />
</parent> <aunt>
<cousin />
</aunt>
</grandparent>
...
Once we’ve found the depth of child when we get to aunt (and then cousin), we don’t need to find the depth of grandparent again. My solution for this was to create a JSON that looks like { node: depth }. Then while we’re in the while loop if we hit a node in our object, we just add the depth of that node to the depth from it to our target node and add the target node to the object. With this method, we never calculate the depth of any given node more than once and our code is much less redundant!
