Performance regression during data load in v17

Hello,

While migrating our codebase to the latest version of Handsontable, we observed a significant degradation in initial load performance. After profiling the application, I identified the source of the issue.

The problem appears to be related to code that executes validators against the source data during hotInstance.loadData(). In our case, no validators are defined, so the validation step itself performs little to no useful work. However, the process still resolves cell metadata for every cell in the dataset.

For our grids, metadata resolution is quite expensive. Our implementation relies on Handsontable’s virtualization behavior, where metadata is typically resolved only for the subset of rows that are rendered (roughly up to 100 rows at a time). With the current behavior, metadata is resolved for the entire dataset during the initial load. Depending on the grid size, this can result in millions of metadata resolution operations.

On a relatively high-performance development machine, this causes the UI to become unresponsive for approximately three seconds during initial load. We expect the impact to be significantly worse for our typical users in production environment.

This regression is currently blocking our migration to version 17, as the resulting user experience is not acceptable for our application.

Requested Enhancement

We would like to request a configuration option that allows this validation-related processing to be skipped entirely. Data validation is not a requirement for our use case, as we already perform validation through custom application logic. Providing a way to disable this step would allow us to avoid the unnecessary metadata resolution overhead and restore acceptable loading performance.

Thanks,

Sandi

cc @dhaber

@shrvic , thank you for the detailed report! I’ll escalate this with the team and update this thread as soon as I have more info.

In the meantime, you may be able to work around it and avoid the full metadata scan by using:

new Handsontable(el, { data: bigData, ... })

instead of hotInstance.loadData() after the table in initialized.

Thank you Joseph for the quick reply.

I noticed that the validators are not executed during HoT initialization, however this is not a viable workaround for us - some of our grids simply don’t have the rows available at the time Handsontable instance is created. We also have (separate) custom events fired at the time HoT is initialized and before and after the rows are loaded among others. If I were to change this in the base grid implementation I would be breaking our internal contracts with many different applications.

Looking forward to your update!

Hi @joseph.petty (and @aleksandra_budnik). This is completely blocking us from upgrading to v17 and we don’t want to fall too far behind. If you can give us some sense of when this will be addressed we can plan accordingly.

Thanks.

Hi @dhaber , @joseph.petty is at a conference, and it may take more time for him to reply.

Could you please message me at support@handsontable.com with more details on exactly what (setups + demos) takes more time? I’d like to debug it.

Hi @dhaber , this regression has been fix and will be in the next release:

1 Like

Awesome, thanks @joseph.petty!

1 Like

Thank you @joseph.petty!

1 Like

Hi @shrvic , this issue has been fixed with the new v18 release. Thanks again for reporting it.

We tested performance and found a substantial improvement on large datasets: on a 100,000 × 100 grid, we measured around a 90% reduction in memory and roughly 30× faster initial render time.

This should resolve the performance issues you were seeing, but please let us know if there are still any issues after updating.

@joseph.petty this fix helps in the simple case, but unfortunately it doesn’t address our actual setup.

Because we have cells configured, the hasRowVaryingMeta check forces execution into the validatePerCell path, which in practice ends up doing the same per-cell metadata resolution work we were seeing before. So even in v18, we still get full-dataset metadata resolution during loadData, not just for the rendered viewport.

In our case, we don’t rely on Handsontable validation at this point since we already handle validation entirely in our application layer. So the validation pipeline (including anything that derives or resolves per-cell metadata as part of it) is pure overhead for us.

Given that, is there any supported way to opt out of validation processing entirely during loadData, or at least bypass the validatePerCell / metadata-resolution path when validation is explicitly disabled?

A potentially good fit here would be a cancellable before* hook that allows opting out of validation during loadData, consistent with existing Handsontable patterns. For example, something like a beforeValidateSourceData hook that can return false to short-circuit the validation pipeline entirely (including the validatePerCell path), rather than introducing a global configuration flag.

Thanks!

Hi @shrvic , I shared this with the team and they are already looking into the fix you suggested.

Thank you again for the report! I’ll post and update as soon as I have an ETA on the fix.