Our blazing fast Grid component built with pure JavaScript


Post by zaclangley »

Columns
export const columns = [
        {
            type: 'rownumber',
            text: '#',
            width: 50,
            locked: true
        },
        {
            field: 'selected',
            type: 'check',
            text: 'Selected',
            width: 80,
            editor: true,
            locked: true
        },
        {
            field: 'firstname',
            text: 'First Name',
            editor: true,
            width: 100,
            locked: true
        },
        {
            field: 'lastname',
            text: 'Last Name',
            editor: true,
            width: 100,
            locked: true
        },
        {
            text: 'Gender',
            field: 'gender',
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 'Male'
                }, {
                    text: 'Female'
                }, {
                    text: 'Other 1'
                }]
            }
            },
        {
            text: 'Race',
            field: 'race',
            default: 'None',
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 'None'
                }, {
                    text: 'Dragonborn'
                }, {
                    text: 'Dwarf'
                }, {
                    text: 'Elf'
                }, {
                    text: 'Gnome'
                }, {
                    text: 'Half-Elf'
                }, {
                    text: 'Halfling'
                }, {
                    text: 'Half-Orc'
                }, {
                    text: 'Human'
                }, {
                    text: 'Tiefling'
                }, {
                    text: 'Goliath'
                }, {
                    text: 'Genasi'
                }, {
                    text: 'Aarakocra'
                }, {
                    text: 'Warforged'
                }, {
                    text: 'Kobold'
                }]
            }
        },
        {
            text: 'Str',
            field: 'str',
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Dex',
            field: 'dex',
            default: 0,
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Con',
            field: 'con',
            default: 0,
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Int',
            field: 'int',
            default: 0,
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Wis',
            field: 'wis',
            default: 0,
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Cha',
            field: 'cha',
            default: 0,
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 8
                }, {
                    text: 9
                }, {
                    text: 10
                }, {
                    text: 11
                }, {
                    text: 12
                }, {
                    text: 13
                }, {
                    text: 14
                }, {
                    text: 15
                }, {
                    text: 16
                }, {
                    text: 17
                }, {
                    text: 18
                }, {
                    text: 19
                }, {
                    text: 20
                }]
            }
        },
        {
            text: 'Class',
            field: 'class',
            default: 'None',
            width: 100,
            editor: {
                type: 'dropdown',
                items: [{
                    text: 'None'
                }, {
                    text: 'Barbarian'
                }, {
                    text: 'Bard'
                }, {
                    text: 'Cleric'
                }, {
                    text: 'Druid'
                }, {
                    text: 'Fighter'
                }, {
                    text: 'Paladin'
                }, {
                    text: 'Ranger'
                }, {
                    text: 'Rogue'
                }, {
                    text: 'Sorceror'
                }, {
                    text: 'Warlock'
                }, {
                    text: 'Wizard'
                }, {
                    text: 'Murder Hobo'
                }]
            }
        },
        {
            field: 'age',
            text: 'Age',
            type: 'number',
            min: 0,
            max: 100,
            width: 80,
            editor: true
        },
        {
            field: 'level',
            text: 'Level',
            type: 'number',
            min: 0,
            max: 100,
            width: 80,
            editor: true
        },
        {
            field: 'rating',
            type: 'rating',
            text: 'Rating',
            max: 7,
            default: 5,
            width: 215,
            editor: false
        },
        {
            field: 'startdate',
            text: 'Start Date',
            type: 'date',
            format: 'MM-DD-YYYY',
            width: 200,
            editor: true
        },
        {
            field: 'enddate',
            text: 'End Date',
            type: 'date',
            format: 'MM-DD-YYYY',
            width: 200,
            editor: true
        },
        {
            field: 'progress',
            text: 'EXP Progress',
            type: 'percent',
            width: 200,
            editor: true
        },
        {
            type : 'template',
            text : 'Location',
            field : 'city',
            template : ({value}) => `Lives in ${value}`,
            width: 120
        },
        {
            type : 'widget',
            text : 'Button Widget',
            field : 'color',
            widgets : [ {
                type: 'button',
                cls: 'b-raised b-orange',
                onClick: () => { console.log('Button Clicked'); }
            }],
            width: 150
        },
        {
            type : 'widget',
            text : 'Power Level',
            field : 'powerlevel',
            widgets : [ {
                type: 'slider',
                min: 0,
                max: 100,
                default: 50,
                onClick: () => { console.log('Button Clicked'); }
            }],
            width: 150
        }
];
Generate Rows
export const generateData = (num: number) => {
    let data: Object[] = [];
    for(let i = 0; i < num; i++) {
        data.push(
            {id: i, selected: false, firstname: 'Jane', lastname: 'Doe', age: 18, str: 18, dex: 16, con: 14, int: 12, wis: 10, cha: 8, level: 3, rating: 6, startdate: '02-10-2018', enddate: '03-10-2018', progress: 23, city: 'Denver', color: 'TPK', gender: 'Male', class: 'Barbarian', race: 'Dragonborn'}
        );
    }
    return data;
};
Main Component
import React from 'react';
import BryntumGrid from '../../../bryntum/BryntumGrid.jsx';
import '../../../bryntum/grid.dark.css';
import './bryntumScheduleMainTable.less';
import { columns } from './columns/bryntumSchedulerMainTableColumns';
import { generateData } from './__mocks__/mockBryntumData';

export class BryntumTableWrapper extends React.Component {

    // @ts-ignore
    private BryntumGridReference: Element;

    setBrytumGridReference = (node) => {
        this.BryntumGridReference = node;
    }

    handleSelectionChange = ({selected, mode}) => {
        if (mode === 'row' && selected.length) {
            this.setState({selectedTeam: selected[0].team || 'None'});
        }
    }

    render() {
        return(
            <div className="bryntum-grid-container">
                <BryntumGrid
                    ref={this.setBrytumGridReference}
                    autoHeight={true}
                    rowHeight={60}
                    // Columns in grid
                    columns={columns}

                    // Rows to display in grid
                    data={generateData(1000)}

                    onSelectionChange={this.handleSelectionChange}
                />
            </div>
        );
    }
}
I'm having some latency issues with 1000 rows and 22 columns.
Is there a virutalization solution that I forgot to implement or am I suppose to keep widget types to a minimum?

Post by pmiklashevich »

Hello,

We've turned your code snippets into a test case and investigated the issue. It is slow since grid is using autoHeight, which makes it to put all rows in DOM. Please try to configure the grid with a height or provide a height using CSS and remove "autoHeight={true}"

Regards,
Pavel

Pavlo Miklashevych
Sr. Frontend Developer


Post by zaclangley »

I turned off Auto-Height and you were right. Performance increased dramatically.

Post Reply