Virtualization in React Tree View
The React Tree View control supports UI virtualization to enhance performance when handling a large amount of data. This feature optimizes rendering by initially gathering all data but only rendering a subset of it during the initial load. The remaining items are then loaded dynamically as the user scrolls within the React Tree View container.
To enable virtualization, set the enableVirtualization property to true and define a fixed height for the React Tree View container.
In the following sample, the enableVirtualization property is enabled.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
function App() {
const totalNodes = 8000;
const employeesPerDept = 20;
const departments = [
'Engineering',
'Sales',
'Human Resources',
'Finance',
'Marketing',
'Customer Support',
'Operations',
'Legal',
'Research',
'IT Infrastructure'
];
const employeeRoles = [
'Manager',
'Senior Engineer',
'Software Engineer',
'Business Analyst',
'QA Engineer',
'Consultant',
'Specialist',
'Coordinator',
'Executive',
'Associate'
];
const generateOrganizationData = (total, children) => {
const data = [];
let index = 0;
let id = 1;
let deptIndex = 0;
while (index < total) {
const deptId = id++;
const deptName = departments[deptIndex % departments.length];
const parentIndex = index;
data[index++] = {
id: deptId,
pid: null,
name: deptName,
hasChild: false,
isChecked: true,
isExpanded: false
};
let childCount = 0;
for (let i = 0; i < children && index < total; i++) {
const role = employeeRoles[i % employeeRoles.length];
data[index++] = {
id: id++,
pid: deptId,
name: `${role} - Employee ${i + 1}`,
isChecked: true,
isExpanded: false
};
childCount++;
}
if (childCount > 0) {
data[parentIndex].hasChild = true;
}
deptIndex++;
}
return data;
};
const orgData = generateOrganizationData(
totalNodes,
employeesPerDept
);
const fields = {
dataSource: orgData,
id: 'id',
parentID: 'pid',
text: 'name',
hasChildren: 'hasChild',
isChecked: 'isChecked',
expanded: 'isExpanded'
};
return (
<div id="treeparent">
<TreeViewComponent
id="treeview"
fields={fields}
enableVirtualization={true}
showCheckBox={true}
height="400px"
/>
</div>
);
}
export default App;
ReactDOM.render(<App />, document.getElementById('sample'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { TreeViewComponent, FieldsSettingsModel } from '@syncfusion/ej2-react-navigations';
interface TreeData {
id: number;
pid?: number | null;
name: string;
hasChild?: boolean;
isChecked?: boolean;
isExpanded?: boolean;
}
function App() {
const totalNodes: number = 8000;
const employeesPerDept: number = 20;
const departments: string[] = [
'Engineering',
'Sales',
'Human Resources',
'Finance',
'Marketing',
'Customer Support',
'Operations',
'Legal',
'Research',
'IT Infrastructure'
];
const employeeRoles: string[] = [
'Manager',
'Senior Engineer',
'Software Engineer',
'Business Analyst',
'QA Engineer',
'Consultant',
'Specialist',
'Coordinator',
'Executive',
'Associate'
];
const generateOrganizationData = (
total: number,
children: number
): TreeData[] => {
const data: TreeData[] = [];
let index: number = 0;
let id: number = 1;
let deptIndex: number = 0;
while (index < total) {
const deptId = id++;
const deptName =
departments[deptIndex % departments.length];
const parentIndex = index;
data[index++] = {
id: deptId,
pid: null,
name: deptName,
hasChild: false,
isChecked: true,
isExpanded: false
};
let childCount: number = 0;
for (
let i = 0;
i < children && index < total;
i++
) {
const role =
employeeRoles[i % employeeRoles.length];
data[index++] = {
id: id++,
pid: deptId,
name: `${role} - Employee ${i + 1}`,
isChecked: true,
isExpanded: false
};
childCount++;
}
if (childCount > 0) {
data[parentIndex].hasChild = true;
}
deptIndex++;
}
return data;
};
const orgData: TreeData[] = generateOrganizationData(
totalNodes,
employeesPerDept
);
const fields: FieldsSettingsModel = {
dataSource: orgData,
id: 'id',
parentID: 'pid',
text: 'name',
hasChildren: 'hasChild',
isChecked: 'isChecked',
expanded: 'isExpanded'
};
return (
<div id="treeparent">
<TreeViewComponent
id="treeview"
fields={fields}
enableVirtualization={true}
showCheckBox={true}
height="400px"
/>
</div>
);
}
export default App;
ReactDOM.render(<App />, document.getElementById('sample'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React TreeView</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="style.css" rel="stylesheet"/>
<link href="https://cdn.syncfusion.com/ej2/35.1.37/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/35.1.37/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
</head>
<body>
<div id='treeparent'>
<div id='sample'>
<div id='loader'>Loading....</div>
</div>
</div>
</body>
</html>@import "@syncfusion/ej2-tailwind3-theme/styles/treeview/index.css";
#treeparent {
display: block;
max-width: 350px;
margin: auto;
overflow: auto;
border: 1px solid #dddddd;
border-radius: 3px;
}Performance benefits
Virtualization provides the following performance benefits:
-
Reduced DOM elements: Only visible nodes are rendered in the DOM, reducing memory consumption.
-
Faster initial load: Large datasets load quickly as only a subset of nodes are rendered initially.
-
Smooth scrolling: Dynamic loading ensures smooth scrolling experience without lag.
-
Lower CPU usage: Rendering fewer elements reduces CPU consumption.
Important notes
- The
heightproperty is required when virtualization is enabled.