Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing large Angular table grid

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?

like image 459
geejay Avatar asked Apr 26 '18 01:04

geejay


2 Answers

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/

like image 175
Pearman Avatar answered Nov 16 '22 21:11

Pearman


I solved this by wrapping the logic with the *ngFor inside into an OnPush component. This makes 300 * 10 inputs display super fast!

like image 2
geejay Avatar answered Nov 16 '22 20:11

geejay