I have run into a performance issue - I can not seem to solve.
Basically I have this dynamic table like structure that works like this
<div class="container">
<div *ngFor="let column of columnData">
<div *ngFor="let rowItem of column.rowItems">
<div [innerHTML]="getHtml(rowItem.info)"></div>
</div>
</div>
</div>
in my component I have a function that takes the rowItem data and then returns some html markup like so
getHtml(data) {
if (...) {
return `
<div>
...
</div>
`
} else if {
return `
<svg>
...
</svg>
`
} else {
...
}
}
now my data structure is as follows
columnData = [
{
columnHeader: 'test'
rowItems: [
{
rowHeader: 'test',
value: 1
},
// ...
]
},
// ...
]
so there may be 100 columns, and each column
has 25 rowItems
- now the rowItems
are almost identical except for the value + some other values I havent displayed but for example the rowHeader
always stays the same.
so for the layout to display correctly, we need to loop through each column
and also loop through each rowItem
- so this becomes a nested for loop. Now with a small amount of data this works fine - but we have quite a lot of data and some objects have 100 columns and 50 rows, so this slows the site down quite considerably - this is the performance
as you can see quite a lot of scripting, now when I remove the nested for loop I get the following
a considerable improvement, but obviously I still need to be able to generate the rowItems.
I have tried using a virtual list - but it is still quite laggy / buggy as it scrolls.
What generally happens is as im scrolling horizontally the whole screen will go white and ill get this warning in the browser
I have also tried progressive rendering, where I only render 10 columns at a time, but this still isnt very performant.
Is there anything else I can do?
Any help would be appreciated
As suggested I tried to implemenet trackBy like so
<div class="container">
<div *ngFor="let column of columnData; trackBy: columnTrackByFn">
<!-- ... -->
<div *ngFor="let rowItem of column.rowItems; trackBy: rowTrackByFn">
<!-- ... -->
</div>
</div>
</div>
columnTrackByFn(index, item) {
return item.colId;
}
rowTrackByFn(index, item) {
return item.rowId;
}
and it didnt help, if anything is made it slower