I am having performance issues when trying to display a grid of editable inputs. It starts to get really slow at around 200 rows and 10 columns. (using Angular 4.4)
<tr *ngFor="let row of rows">
<td *ngFor="let column of columns">
<ng-container [ngSwitch]="column.columnType">
<ng-template [ngSwitchCase]="0">
<input [(ngModel)]="row[column.index].value" ...>
</ng-template>
<ng-template [ngSwitchCase]="1">
<select ...>
</ng-template>
<ng-template [ngSwitchCase]="2">
<span ...>
</ng-template>
<ng-template [ngSwitchCase]="...">
<div ...>
</ng-template>
<ng-template [ngSwitchCase]="15">
<a href ...>
</ng-template>
</ng-container>
</td>
</tr>
There is a lot of time taken (according to the Chrome profiler - debugUpdateDirectives) in the switch statement as well as . Any ideas on how to reduce this?
You will probably want to use trackBy
. You can add this additional piece to each of your *ngFor
's to help Angular know whether or not each slice needs to be redrawn. It will use the value returned by trackBy
to determine whether or not the row is dirty (i.e. lastTrackByResult === currentTrackByResult
).
<tr *ngFor="let row of rows; trackBy: rowTrackByFunction">
And then in your controller:
rowTrackByFunction(index, item) {
// You will want to return a unique primitive for angular to use as a comparison item
// (string, number, etc.)
return item.someUniqueIdentifier;
}
See this link for more info:
https://netbasal.com/angular-2-improve-performance-with-trackby-cc147b5104e5
P.S. If the performance becomes really important you might consider using a pre-made table component that comes with built-in virtual scrolling. I would recommend NGX-Datable, which can easily handle thousands of rows by only drawing what the user can currently see. http://swimlane.github.io/ngx-datatable/
I solved this by wrapping the logic with the *ngFor inside into an OnPush component. This makes 300 * 10 inputs display super fast!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With