Search results

Immutable Mode in JavaScript TreeGrid control

22 Jul 2021 / 3 minutes to read

The immutable mode optimizes the Tree Grid re-rendering performance by using the object reference and deep compare concept. When performing the Tree Grid actions, it will only re-render the modified or newly added rows and prevent the re-rendering of the unchanged rows.

To enable this feature, you have to set the enableImmutableMode property as true.

  • This feature uses the primary key value for data comparison. So, you need to provide the isPrimaryKey column.
Source
Preview
index.ts
index.html
Copied to clipboard
import { TreeGrid, Page, Edit } from '@syncfusion/ej2-treegrid';
import { sampleData2, dataSource1, sampleData } from './datasource.ts';

TreeGrid.Inject(Page, Edit);

let immutableStart: any;
let normalStart: any;
let immutableInit = true;
let init = true;
if(sampleData2.length == 0){
  dataSource1();
}

    let immutableGrid: TreeGrid = new TreeGrid(
        {
            dataSource: sampleData2,
            childMapping: 'subtasks',
            height: 350,
            allowPaging: true,
            pageSettings: {pageSize: 50},
            treeColumnIndex: 1,
            enableImmutableMode: true,
            selectionSettings: { type: "Multiple" },
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
            beforeDataBound: () => {
                immutableStart = new Date().getTime();
            },
            dataBound: ()=> {
            let val = immutableInit ? '' : new Date().getTime() - immutableStart;
            document.getElementById('immutableDelete').innerHTML = 'Immutable rendering Time: ' + "<b>" + val + "</b>" + '<b>ms</b>';
            immutableStart = 0; immutableInit = false;
            },
            columns: [
                { field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 70, textAlign: 'Right' },
                { field: 'taskName', headerText: 'Task Name', width: 200, textAlign: 'Left' },
                { field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'endDate', headerText: 'End Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
                { field: 'progress', headerText: 'Progress', width: 80, textAlign: 'Right' },
                { field: 'priority', headerText: 'Priority', width: 90 }
            ]
        });
    immutableGrid.appendTo('#immutable');
document.getElementById('delete').addEventListener('click', function(e) {
  normalGrid.selectRows([0, 2, 4]);
  immutableGrid.selectRows([0, 2, 4]);
  normalGrid.deleteRecord();
  immutableGrid.deleteRecord();
});
document.getElementById('addtop').addEventListener('click', function(e) {
  normalGrid.addRecord(sampleData[0], 0, "Top");
  immutableGrid.addRecord(sampleData[0], 0, "Top");
});
document.getElementById('addbottom').addEventListener('click', function(e) {
  normalGrid.addRecord(sampleData[0], 0, "Bottom");
  immutableGrid.addRecord(sampleData[0], 0, "Bottom");
});
document.getElementById('reverse').addEventListener('click', function(e) {
  let aData = (immutableGrid.dataSource as any).reverse();
  normalGrid.setProperties({ dataSource: aData });
  immutableGrid.setProperties({ dataSource: aData });
});
document.getElementById('paging').addEventListener('click', function(e) {
  let page = normalGrid.pageSettings.currentPage + 1;
  normalGrid.goToPage(page);
  immutableGrid.goToPage(page);
});
let normalGrid: TreeGrid = new TreeGrid({
    dataSource: sampleData2,
    childMapping: 'subtasks',
    height: 350,
    allowPaging: true,
    selectionSettings: { type: "Multiple" },
    editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
    pageSettings: {pageSize: 50},
    treeColumnIndex: 1,
    beforeDataBound: () => {
        normalStart = new Date().getTime();
    },
    dataBound: ()=> {
        let val = init ? '' : new Date().getTime() - normalStart;
        document.getElementById('normalDelete').innerHTML = 'Normal rendering Time: ' + "<b>" + val + "</b>" + '<b>ms</b>';
        normalStart = 0; init = false;
    },
    columns: [
                { field: 'taskID', headerText: 'Task ID',  isPrimaryKey: true, width: 70, textAlign: 'Right' },
                { field: 'taskName', headerText: 'Task Name', width: 200, textAlign: 'Left' },
                { field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'endDate', headerText: 'End Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
                { field: 'progress', headerText: 'Progress', width: 80, textAlign: 'Right' },
                { field: 'priority', headerText: 'Priority', width: 90 }
    ]
});
normalGrid.appendTo('#normal');
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Tree Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Tree Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
     <!-- Syncfusion Essential JS 2 Styles -->
    <link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/material.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<style>
    .immutablegrid,
    .normalgrid {
        pointer-events: none;
    }
</style>
<body>
   <div id='loader'>Loading....</div>
    <div id='container'>
        <table>
            <tbody>
                <tr>
                    <td>
                        <span id='immutableDelete'></span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <span id='normalDelete'></span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div>
                            <button id="addtop" class="e-control e-btn e-lib e-info">Add row at top</button>
                            <button id="addbottom" class="e-control e-btn e-lib e-info">Add row at bottom</button>
                            <button id="delete" class="e-control e-btn e-lib e-info">Delete 5 rows</button>
                            <button id="reverse" class="e-control e-btn e-lib e-info">Sort Task ID</button>
                            <button id="paging" class="e-control e-btn e-lib e-info">Paging</button>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <span><b>Immutable Tree Grid</b></span>
                        <div id='immutable' class="immutablegrid"></div>
                    </td>
                    <td>
                        <span><b>Normal Tree Grid</b></span>
                        <div id='normal' class="normalgrid"></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>  
</body>
</html>

Limitations

The following features are not supported in the immutable mode:

  • Frozen rows and columns
  • Row Template
  • Detail Template
  • Column reorder
  • Virtualization