Datagrid with custom column renderer very slowly

Hi Team,

We create table timesheet 31 columns related with all days in month. User can directly edit on any cell.
Its work but we meet terrible issue with performance when number of row > 5… Very very slowly to create inline new row. We lost >10s or more to create one new row.
Here is my example code we try with ComponentRenderer
private void initDayColumns(){
for (int i=1; i<=31; i++) {
String fieldName = “day” + String.valueOf(i);
Renderer renderColumn = new ComponentRenderer<>(item → {
return createMyComponent(fieldName,item);
});
detailDataGrid.getColumnByKey(fieldName).setRenderer(renderColumn);
}
}

We try other render method with LitRenderer like this:
Renderer renderColumn = LitRenderer.of(
“<timesheet-detail " +
" .listData=”${item.listData}" " +
" .listType="${item.listType}" " +
" .listUnit ="${item.listUnit}" " +
“>” +
“”
) .withProperty(“listData”,dto → getListData(dto))
.withProperty(“listType”,dto → getListType(dto) )
.withProperty(“listUnit”,dto → getListUnit(dto) );
detailDataGrid.getColumnByKey(fieldName).setRenderer(renderColumn);
It quire better util we bind data (its very small array, example .withProperty(“listData”,dto → getListData(dto)) ) to our template component “timesheet-detail” , performance same as ComponentRenderer method.
Datagrid like this:
image
We think the table with ~40 column it not very big for enterprise application. because timesheet table its standard and not have any special requirement.
Please help us to investigate this issue or you have any solution to suggest us to make timesheet table bring to end user with smart and comfortable.
Thank you very much!

Hi,

Could you please attach small demo project that reproduces the issue?

Regards,
Gleb

1 Like

Sure, we will prepare and attach later.
Thank you!

Dear Mr. Gleb Gorelov,

Here is sample project:
inlineedit.zip (1.1 MB)
Please help us!

Hi,

Thank you for the demo project. The performance issue has nothing with DataGrid. The problems are in code that handle changes. For example:

  • onDetailDcCollectionChange - every time it called it handles all existing items, regardless of changes. For example. when you create a first item, CollectionChangeEvent fires twice for REFRESH and ADD_ITEM change type and you handle 31 days twice (since you have a single item, i.e. 62 times). When you add 2nd items, CollectionChangeEvent fires twice for REFRESH and ADD_ITEM change type and you iterate over days of 2 items twice, i.e. 124 times. The number of operations increases exponentially every time you add a new item. To see it, add logger inside detailsList.forEach() code block.
  • You use Fragments to render columns, but it is important to remember that fragments, although they are components, are more heavy than simple components, because they are closer to screens, for example, it can create and store data containers. For example each TimesheetEmployeeCellFragment contains employeesDc and loads Employee entities every time Fragment is created, which means every row in the DataGrid loads the same list of Employees and every time you add item or change it DataGrid rerenders columns, i.e. fragments are recreated and data reloaded.

These are just a few things I noticed at first glance.

Regards,
Gleb

Thank you Mr. Gleb Gorelov.
We will try other way.