Skip to content

Commit

Permalink
Add performance comparison with the 2 most popular react trees on npm
Browse files Browse the repository at this point in the history
- rc-tree
- react-accessible-treeview

Signed-off-by: leslielazzarino <[email protected]>
  • Loading branch information
leslielazzarino committed Feb 16, 2024
1 parent ebb9276 commit 396e926
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 4 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
"@mui/icons-material": "^5.11.16",
"@mui/material": "^5.12.3",
"@mui/system": "^5.11.15",
"ash-tree": "link:./ash-tree/build/",
"rc-tree": "^5.8.5",
"react": "^18.2.0",
"react-accessible-treeview": "^2.8.3",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ash-tree": "link:./ash-tree/build/",
"web-vitals": "^3.3.2",
"rc-tree": "^5.8.5",
"react-accessible-treeview": "^2.8.3"
"web-vitals": "^3.3.2"
},
"devDependencies": {
"@testing-library/dom": "^9.3.1",
Expand Down
43 changes: 43 additions & 0 deletions src/Components/RcTreeComparison/RcTreeBasic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
// SPDX-FileCopyrightText: Leslie Lazzarino <[email protected]>
// SPDX-FileCopyrightText: Benedikt Richter <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0

import React, { ReactElement } from 'react';
import '../../styles.css';
import { testNodes } from '../shared';
import Tree from 'rc-tree';
import { NodesForAshTree } from 'ash-tree';

// Main drawbacks of this library found so far: lack of examples, typing really difficult to understand, huge package
// size, unusable default structure (no indentation, no collapsing/expanding)
export function RcTreeBasic(): ReactElement {
const treeData = getTreeData(testNodes);

return (
<div className="tree-box">
<h1>Basic Tree</h1>
<Tree expandAction={'click'} treeData={treeData} />
</div>
);
}

function getTreeData(
nodes: NodesForAshTree,
path: string = '',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): any {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const treeData: any = [];
for (const name of Object.keys(nodes)) {
const node = nodes[name];
treeData.push({
key: `${path}/${name}`,
title: name ? name : '/',
children: node && node !== 1 ? getTreeData(node) : undefined,
});
}

return treeData;
}
31 changes: 31 additions & 0 deletions src/Components/RcTreeComparison/__tests__/performance.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
// SPDX-FileCopyrightText: Leslie Lazzarino <[email protected]>
// SPDX-FileCopyrightText: Benedikt Richter <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0

import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { RcTreeBasic } from '../RcTreeBasic';

describe('The BasicTree', () => {
it('takes so long to expand and collapse 100 times', () => {
render(<RcTreeBasic />);

logTimeTakenToExpandAndCollapseRoot100TimesRcTree();
});
});

export function logTimeTakenToExpandAndCollapseRoot100TimesRcTree(): void {
const startTime = new Date().getTime();
for (let i = 0; i < 100; i++) {
fireEvent.click(screen.getByText('/'));
fireEvent.click(screen.getByText('/'));
}
const endTime = new Date().getTime();
console.log(
'Time taken to render the basic rc tree 100 times: ',
endTime - startTime,
'ms',
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
// SPDX-FileCopyrightText: Leslie Lazzarino <[email protected]>
// SPDX-FileCopyrightText: Benedikt Richter <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0

import React, { ReactElement } from 'react';
import '../../styles.css';
import { testNodes } from '../shared';
import { NodesForAshTree } from 'ash-tree';
import TreeView, { INode } from 'react-accessible-treeview';
import { IFlatMetadata } from 'react-accessible-treeview/dist/TreeView/utils';

// Main drawbacks of this library found so far: only one root node allowed
export function ReactAccessibleTreeviewBasic(): ReactElement {
const treeData = getTreeData({ home: testNodes });

const nodeRenderer = ({
element,
getNodeProps,
level,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
handleSelect, // eslint-disable-next-line @typescript-eslint/no-explicit-any
}: any): ReactElement => (
<div {...getNodeProps()} style={{ paddingLeft: 20 * (level - 1) }}>
{element.name}
</div>
);

return (
<div className="tree-box">
<h1>Basic Tree</h1>
<TreeView
defaultExpandedIds={['/home']}
data={treeData}
nodeRenderer={nodeRenderer}
/>
</div>
);
}

function getTreeData(
nodes: NodesForAshTree,
parentPath: string | null = null,
treeData: INode<IFlatMetadata>[] = [],
): INode<IFlatMetadata>[] {
for (const name of Object.keys(nodes)) {
const displayName = name || '/';
const node = nodes[name];
const nodePath = `${parentPath || ''}/${displayName}`;
treeData.push({
id: nodePath,
parent: parentPath,
name: displayName,
children:
node !== 1
? Object.keys(node).map(
(childName: string) => `${nodePath}/${childName || '/'}`,
)
: [],
});
if (node !== 1) {
getTreeData(node, nodePath, treeData);
}
}

return treeData;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
// SPDX-FileCopyrightText: Leslie Lazzarino <[email protected]>
// SPDX-FileCopyrightText: Benedikt Richter <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0

import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { ReactAccessibleTreeviewBasic } from '../ReactAccessibleTreeviewBasic';

describe('The BasicTree', () => {
it('takes so long to expand and collapse 100 times', () => {
render(<ReactAccessibleTreeviewBasic />);

logTimeTakenToExpandAndCollapseRoot100TimesRcTree();
});
});

export function logTimeTakenToExpandAndCollapseRoot100TimesRcTree(): void {
const startTime = new Date().getTime();
for (let i = 0; i < 100; i++) {
fireEvent.click(screen.getByText('/'));
fireEvent.click(screen.getByText('/'));
}
const endTime = new Date().getTime();
console.log(
'Time taken to render the basic rc tree 100 times: ',
endTime - startTime,
'ms',
);
}

0 comments on commit 396e926

Please sign in to comment.