Skip to content

Commit

Permalink
Merge pull request #42 from lol-russo/add-react-tree-size
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreardon authored Jul 6, 2020
2 parents 6bc26be + 3823089 commit ce3807a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
52 changes: 51 additions & 1 deletion src/tasks/preset/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ReactDOM from 'react-dom';
import ReactDOMServer from 'react-dom/server';
import {
RunStaticTaskArgs,
RunStaticTaskArgsWithReactRoot,
RunTimedTaskArgs,
StaticTask,
TaskGroup,
Expand Down Expand Up @@ -123,10 +124,59 @@ const completeRender: TimedTask = timedTask({
},
});

interface Fiber {
// Singly Linked List Tree Structure.
// Full type here https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactInternalTypes.js
child: Fiber | null;
sibling: Fiber | null;
}

export function traverse(rootNode: Fiber, callback: (node: Fiber) => void) {
function walk(node: Fiber) {
// First call the callback on the node.
callback(node);

if (!node.child && !node.sibling) {
return;
}

// Then recursively call the walk function on each child and sibling.
node.child && walk(node.child);
node.sibling && walk(node.sibling);
}

walk(rootNode);
}

const reactFiberNodeCount: StaticTask = staticTask({
name: 'React Fiber node count',
description: `
The number of React Elements or internal objects ("fibers") that hold information about the component tree state.
`,
run: async ({ getElement, container }: RunStaticTaskArgsWithReactRoot): Promise<string> => {
ReactDOM.render(getElement(), container);

const fiberRoot = container?._reactRootContainer?._internalRoot?.current;

let count = 0;
fiberRoot && traverse(fiberRoot, () => count++);

return String(count);
},
});

const group: TaskGroup = {
groupId: 'Client',
name: 'Client 👩‍💻',
tasks: [render, reRender, hydrate, domElementCount, domElementCountWithoutSvg, completeRender],
tasks: [
render,
reRender,
hydrate,
domElementCount,
domElementCountWithoutSvg,
completeRender,
reactFiberNodeCount,
],
};

export default group;
9 changes: 8 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ type BaseTask = {
description: string;
};

interface Container extends HTMLElement {
_reactRootContainer?: any;
}

export type RunStaticTaskArgs = {
getElement: () => React.ReactElement;
container: HTMLElement;
};

export type RunStaticTaskArgsWithReactRoot = {
getElement: () => React.ReactElement;
container: Container;
};
export type StaticTask = BaseTask & {
scale?: string;
type: 'static';
Expand Down

0 comments on commit ce3807a

Please sign in to comment.