How to handle a lot of cells with editable data?

Tags: #<Tag:0x00007f8b19f231f8>

Hello!
I am working in a project that handle a huge amount of rows and cols ( 4000 x 30).
This information comes from an endpoint, the response is not taking a long time (just some milliseconds). Unfortunately, the render method is taking a long time (the loading wheel is only available for the API call, not for the render time).
This is more or less the code :slight_smile:

 <HotTable
                  beforeChange={this._onChange}
                  renderAllRows={false}
                  cells={this._cellsHook}
                  fixedColumnsLeft={6}
                  exporting={this.exportButtonId}
                  root={'******'}
                  colHeaders={this._getColumnHeaders()}
                  columns={this._getColumnDefinitions()}
                  stretchH={'all'}
                  licenseKey={HANDSONTABLE_LICENSE}
                  height={this.props.tableHeight || height}
                  width={width}
                  data={this.props.rowData}
                 
                /> 

On the other hand, I have updated to the latest version: 7.4.2, because I have seen that was some improvements on performance. I have to mention that after this update it is working sort of better in chrome, but a bit worst on IE (our standard browser at the moment). We upgraded from handsontable-pro:2.0.0 to handsontable:7.4.2

I have seen this topic, but the demo seems to be not working anymore: Best approach to show huge data in handsontable grid

Thank you!

Best regards,

Hey Jose!

What’s going on here ?

please share your beforeChange and cells logic.

Hi Aleksandra!

in BeforeChange function, we have some validations for saving. We have made a validation of the source that only works when is not loading data.

in Cells attribute, we set some readonly columns according with some business logic.

I am working into some logging to check when each method takes. Ex.:

  1. How long takes the API call
  2. How long takes the parsing from JSON to estructured Object
  3. How long takes the render

Thank you!

4000 x 30 dataset is not too much to handle for Handsonable. I would suspect that the beforeChange triggers to many calls to the browser to keep up with the performance.
Can you share it via demo?

Hello Aleksandra,

This is more or less the code :slight_smile:

I feel more peaceful that you said that 4000 * 30 is not that many!

private _onChange(changes: HotChange[], source: string) {

    if (source !== 'loadData') {

      const metadata: ApplyItemChangeMetadata = {

        chapters: this.props.chaptersReverseMap,

        costTypes: this.props.costTypesReverseMap,

        currencies: this.props.currenciesReverseMap,

      };

      const payload = map(changes, ([row, column, oldValue, newValue]) => ({

        oldValue,

        newValue: validateInput(

          newValue,

          getSetStringForField(column.toString())[1],

          metadata,

        ),

        field: column.toString(),

        grandParentId: this.props.rowData[row].grandParentId,

        parentId: this.props.rowData[row].parentId,

        id: this.props.rowData[row].id,

        rowType: this.props.rowData[row].type,

      }));

      const validatedPayload = filter(payload, i => !isNil(i.newValue) || (isNil(i.newValue) && (i.field == "paidDate" || i.field == "actualContractDate")));

      

      if (validatedPayload.length > 0) {

        this.props.tableChanges(validatedPayload);

      } else {

        return false;

      }

    }

  }

private _cellsHook(row: number, _col: number | string, prop: string) {

    const cellProps: CellProps = {};

    if (this.props.rowData[row]) {

      if (this.props.rowData[row].type === RowType.ACTIVITY) {

        if (!this.activityEditableFields[prop]) {

          cellProps.readOnly = true;

        }

        cellProps.rowType = RowType.ACTIVITY;

      }

      if (this.props.rowData[row].type === RowType.CHAPTER) {

        if (!this.chapterEditableFields[prop]) {

          cellProps.readOnly = true;

        }

        cellProps.rowType = RowType.CHAPTER;

      }

      if (this.props.rowData[row].type === RowType.SUBACTIVITY) {

        if (!this.subActivityEditableFields[prop]) {

          cellProps.readOnly = true;

        }

        cellProps.rowType = RowType.SUBACTIVITY;

      }

    }

    return cellProps;

  }

Thank you!

That doesn’t seem to be too ‘heavy’ for the first glance.

Does commenting out the

const validatedPayload = filter(payload, i => !isNil(i.newValue) || (isNil(i.newValue) && (i.field == "paidDate" || i.field == "actualContractDate")));

      

      if (validatedPayload.length > 0) {

        this.props.tableChanges(validatedPayload);

      } else {

        return false;

      }

changes anything?

Hello Aleksandra,

I have commented out that part of my code, but seems to be slow as it it was before.
Unfortunately, I cannot share any screenshot.

As I do not have a full working demo I can suggest to comment out one option at a time and compare results. Then we will be able to find the operation/hook that makes it slow.

Hello again!

Aparently, I saw the same results commenting these two methods.
I will try to measure the time in each event and come back :slight_smile:

1 Like

Hello Aleksandra!

So sorry to reply this a bit late.
Okay, I have done some time measurements on react. So, this is a bit old fashion to do it, but I guess it could help a bit.

So, I wanted to divide the analysis in three different parts.

  1. Data download from REST API
  2. Data conversion from JSON to complex objects (some categories and subcategories)
  3. Rendering

These were the times:

  1. Data download from REST API: 1 millisecond
  2. Data conversion from JSON to complex objects : 1 millisecond (You will notice the array contains 1152 objects)
  3. Rendering: I could not measure because I did not how to do it, just added some console logs on Handsontable component (as shown in the picture attached), but is not possible to me set a timer log when it finished to render. I took the time and it is always circa of 20 seconds since the step 2 ends. If you see the log “Finished initialization 
”. That message depends of a indicator in the code that shows or hide a loader bar. After it is hidden, it takes around 20 seconds to show the handsontable component.

I know it is hard to check, but do you have some suggestions what to do? How to time it or if we should contact someone from Handsontable support :slight_smile: ?

Thank you so much!!!

I have forgotten to mention that I am seeing this message in the console as well:

Great research! I will ask our Engineer to take a look at this.

Hi @jlsuarezcabrera

Yes, great research.
Unfortunately, without a demo, it’s hard to say much more.

If you have extended support we could investigate your case further.
Could you send your license key to support@handsontable.com?

1 Like

Done :wink: Thank you!