Last active
March 14, 2024 13:24
-
-
Save JamesIves/b05f77a6e4f215dd37cd9425769c4dad to your computer and use it in GitHub Desktop.
Walks the DOM and creates a table based on how many elements it occurs in the light and shadow DOM, along with a combined total separated by a coloured header. Useful for tracking down performance issues with excessive DOM nodes. Can be run in the browser dev tools console.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Walk the DOM tree and tally the number of elements between light and shadow dom. | |
*/ | |
function walkDOM(root, nodeCounts = {}, shadowNodeCounts = {}, isShadow = false) { | |
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT); | |
const nodes = []; | |
const excludedNodes = ['META', 'SCRIPT', '#text']; // Add any other node types you want to exclude | |
while(walker.nextNode()) { | |
if (!excludedNodes.includes(walker.currentNode.nodeName)) { | |
nodes.push(walker.currentNode); | |
const counts = isShadow ? shadowNodeCounts : nodeCounts; | |
counts[walker.currentNode.nodeName] = (counts[walker.currentNode.nodeName] || 0) + 1; | |
} | |
if (walker.currentNode.shadowRoot) { | |
const shadowResult = walkDOM(walker.currentNode.shadowRoot, nodeCounts, shadowNodeCounts, true); | |
nodes.push(...shadowResult.nodes); | |
} | |
} | |
return { nodes, nodeCounts, shadowNodeCounts }; | |
} | |
function findMostEncounteredNodes(nodeCounts, label, color) { | |
// Convert the nodeCounts object to an array of [node, count] pairs | |
const nodeCountPairs = Object.entries(nodeCounts); | |
// Sort the array by count in descending order | |
nodeCountPairs.sort((a, b) => b[1] - a[1]); | |
// Log all node types with colored header | |
console.log(`%cNodes in ${label}:`, `color: ${color}`); | |
console.table(nodeCountPairs); | |
} | |
const { nodes, nodeCounts, shadowNodeCounts } = walkDOM(document); | |
findMostEncounteredNodes(nodeCounts, 'light DOM', 'blue'); | |
findMostEncounteredNodes(shadowNodeCounts, 'shadow DOM', 'green'); | |
// Combine light and shadow DOM counts | |
const combinedCounts = { ...nodeCounts }; | |
for (const node in shadowNodeCounts) { | |
combinedCounts[node] = (combinedCounts[node] || 0) + shadowNodeCounts[node]; | |
} | |
findMostEncounteredNodes(combinedCounts, 'combined light and shadow DOM', 'red'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment