[GH #2538] Angular performance issues

I’ve integrated HOT into a complex angular application, and whilst it largely works, there are a few issues that I’ve encountered that I’ve not been able to get around.

Firstly, performance seems to be taking a hit due the methods in the configuration options being run every time Angular detects changes. In our case, we’ve got methods that convert structured data into the array format the HOT requires, and other methods which listen for changes to data and sync those changes with the backend structure. An example of this config is below. The logging statements are being output to the console on every change detection cycle, not just on updates to the table data:

    return {
      afterValidate: isValid => {
        this.validateTable(isValid)
      },
      afterChange: (changes, source) => {

		console.log('changes function running')

        if (source === 'loadData' || !changes) {
          return
        }

        // Sync the value change in the HOT instance back to the answer
        // eslint-disable-next-line
        changes?.forEach(([row, column, oldValue, newValue]) => {
          tableData.data[row][column.toString()]['value'] = newValue
        })
        const rawData = this.hotRegisterer.getInstance(this.question().id).getData()
        tableData.data.forEach((row, r: number) => {
          row.forEach((cell: Cell, c: number) => {
            cell.renderedValue = rawData[r][c]
          })
        })
        this.tableData.set(tableData)
      },
      // ...
      data: tableData ? this.rawTableData() : [],
      // ...
      cells: (row, col) => {
        
        console.log('cell function running')

        const val = tableData.data[row][col]?.value
        const calculated = typeof val === 'string' && val.startsWith('=')
        const format = {
          readOnly: calculated,
          className: calculated ? 'calculated-cell htMiddle' : 'htMiddle',
          type: tableData.data[row][col]?.numbersOnly ? 'numeric' : 'text'
        }

        if (tableData.data[row][col]?.currency) {
          format['numericFormat'] = {
            pattern: '0,0.00 $'
          }
        }

        return format
      }
}

The other issue that appears regularly is that the column headers don’t horizontally scroll with the table contents. I’ve included an image below to illustrate this:

I think this might have something todo with this issue, as it sometimes remedies if the page structure changes via hide/show operation etc: Angular: Validating cells causes 'Uncaught TypeError: Cannot read properties of undefined (reading 'startRow')' · Issue #11631 · handsontable/handsontable · GitHub.

This doesn’t appear to be a CSS issue either as removing custom styles doesn’t rectify things.

Any pointers for the above appreciated.

Hi @tim8987

The first issue is due to the current architecture of Handsontable. It constantly watch for any change and update/re-render internally if it detects the smallest alteration. To minimize the impact of this mechanism you can try using batching to execute multiple actions in one batch: Batch operations - Angular Data Grid | Handsontable

We also just released Handsontable 16.0, which includes our new, improved version of the Angular wrapper to make it easier to work with current versions of Angular.

As for the second issue, yes, I can confirm that it’s most likely caused by this issue. We have it also reported internally so I will update you once we have the fix ready.