primereact
primereact copied to clipboard
DataTable: [Violation] 'input' handler took <N>ms
Describe the bug
I have a use case for the DataTable which seems to be hitting some limits of the component.
My use case is that I have a table with 38 columns, which has thousands of entries hence it's connected with the back-end API to do the pagination and filtering.
We make use of PrimeReact filter UI with filterDisplay set to menu, now when trying to input a certain value in any of the one columns, the input handler takes time to take place, usually it's about 500ms for a simple input change. Which shows with this error: [Violation] 'input' handler took 528ms
Also, when the table first renders it shows similar messages but for different handlers, which are:
[Violation] 'setTimeout' handler took 545ms
[Violation] 'message' handler took 492ms
When I'm running the profiler to find the bottleneck, I see that for each input change the whole table gets re-rendered. I think it's best to not trigger a full re-render until the Apply is clicked. That is one assumption that I have, if there is an option that I'm missing please let me know.
Reproducer
No response
System Information
System:
OS: macOS 12.5.1
CPU: (10) x64 Apple M1 Pro
Memory: 21.35 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 22.2.0 - ~/.nvm/versions/node/v22.2.0/bin/node
npm: 10.7.0 - ~/.nvm/versions/node/v22.2.0/bin/npm
pnpm: 9.11.0 - ~/Desktop/**/node_modules/.bin/pnpm
Browsers:
Chrome: 129.0.6668.101
Safari: 15.6.1
npmPackages:
primereact: ^10.8.2 => 10.8.3
react: ^18.3.1 => 18.3.1
tailwindcss: ^3.4.10 => 3.4.13
Steps to reproduce the behavior
- Make use of DataTable component
- Have a list with 38 columns and thousands of entries
- Map that data as below:
<DataTable
stripedRows
showGridlines
rowHover
lazy
scrollable
resizableColumns
rows={meta?.per_page}
totalRecords={meta?.total}
paginator
paginatorPosition="top"
paginatorTemplate={paginatorTemplate}
columnResizeMode="expand"
scrollHeight="700px"
reorderableColumns
value={data}
filterDisplay="menu"
size="small"
first={meta?.from}
tableStyle={{ tableLayout: 'fixed' }}
filters={tableFilters}
onColReorder={onColReorder}
onPage={onPage}
onFilter={onFilter}
>
{visibleColumns.map((col) => (
<Column
key={`${col.field}-${name}`}
field={col.field}
columnKey={col.field}
filter={col.filter}
body={(rowData: D, options) => customBodyTemplate(rowData, options, col.body)}
header={col.header}
filterField={col.field}
filterElement={col.filterElement}
expander={col.expander}
style={{ width: '240px' }}
headerStyle={{ width: '240px' }}
bodyStyle={{ width: '240px' }}
/>
))}
{actionButtons && (
<Column body={actionButtons} header="Aktionen" exportable={false} style={{ width: '8rem' }} />
)}
</DataTable>
### Expected behavior
All the handlers should be handled in an optimal way so large data sets don't get impacted.
Most likely related to https://github.com/primefaces/primereact/issues/6811
EDIT: I solved it by creating my own filter and instead of using onChange, I used onBlur
const filterString= (opt: ColumnFilterElementTemplateOptions) => {
return (
<InputText
defaultValue={opt.value}
onBlur={(e) => opt.filterCallback(e.currentTarget.value)}
/>
);
};
<Column filterElement={filterString)} />
This is just an example, you must set up a filter of the ideal type for your column type