Angular 6 MatTable Performance in 1000 rows.

前端 未结 7 799
無奈伤痛
無奈伤痛 2020-12-03 04:56

I\'m using angular material in my project and I\'m using Mat-Table to render 1000 Product/row per table. When Change pagination (we use backend pagination) of table to 1000

相关标签:
7条回答
  • 2020-12-03 05:29

    Not sure if this will help your situation as there's no code but we've found that the MatTable loads very slowly if a large data set is set before you set the datasource paginator.

    For example - this takes several seconds to render...

    dataSource: MatTableDataSource<LocationItem> = new MatTableDataSource();
    @ViewChild(MatSort) sort: MatSort;
    @ViewChild(MatPaginator) paginator: MatPaginator;
    
    ngOnInit() {
      this.dataSource.data = [GetLargeDataSet];
    }
    
    ngAfterViewInit() {
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
    }
    

    ...but this is fast

    ngOnInit() {
      // data loaded after view init 
    }
    
    ngAfterViewInit() {
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
    
      /* now it's okay to set large data source... */
      this.dataSource.data = [GetLargeDataSet];
    }
    

    Incidentally, we were only finding this issue the second time we access the component as the large dataset from server was being cached and was immediately available the second time component was accessed. Another option is to add .delay(100) to your observable if you want to leave that code in the ngOnInit function.

    Anyway, this may or may not help your situation.

    0 讨论(0)
  • 2020-12-03 05:30

    I was having an issue with Turneye's answer giving me an "expressionchangedafterithasbeencheckederror", so I took inspiration from jabu.hlong's answer. It turned 5-10 seconds of load time into less than a second.

    ngAfterViewInit() {
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
    
      setTimeout(() => {
        this.dataSource.data = getData(); // Or whatever your data source is
      });
    }
    

    A side note (mentioned because it seems to be in the same class of issue as the one I was having): I have found it best practice to set the sort before the paginator, because I have run into issues with the reverse when setting matSortActive.

    EDIT: Fixed issues with brackets and semicolons.

    0 讨论(0)
  • 2020-12-03 05:32

    Introduce pagination. That's the only way to solve performance issue in the mat-table.

    https://material.angular.io/components/table/overview#pagination

    0 讨论(0)
  • 2020-12-03 05:41

    To extend upons @Turneye 's answer. The reason it's happening is because the paginator is being set after all the rows have been rendered, because that's what the ngAfterViewInit hook tells you.

    So it first renders all rows from data source, then it sees: "hey, I'm getting a paginator, let me just remove all the rows (except the pager count)". This is obviously very slow on large data sets and/or complex table cell templates.

    You can solve this by using the {static: true} option on your @ViewChild. This will make the paginator available inside the ngOnInit lifecycle hook, and before any row has been rendered:

    To steal his code, you can change it to this, and still have a fast table:

    readonly dataSource: MatTableDataSource<LocationItem> = new MatTableDataSource();
    
    @ViewChild(MatSort, { static: true }) sort: MatSort;
    @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
    
    ngOnInit() {
      this.dataSource.data = [ GetLargeDataSet ];
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
    }
    

    Be aware though that this will not work if your mat-paginator is inside a structural directive like *ngIf


    Another performance issue could be that you have to declare a trackBy function:

    To improve performance, a trackBy function can be provided to the table similar to Angular’s ngFor trackBy. This informs the table how to uniquely identify rows to track how the data changes with each update.

    <table mat-table [dataSource]="dataSource" [trackBy]="myTrackById">
    
    0 讨论(0)
  • 2020-12-03 05:42

    I had solved this issue and i improved the performance by wrap the table in custom (grid) component and Control the changeDetection of the component to be ChangeDetectionStrategy.OnPush and when i want to render update i used ChangeDetectorRef.detectChanges()

    0 讨论(0)
  • 2020-12-03 05:51

    I have found the paginator and sort to sometimes not work.

    What has worked for me with over 2000 rows was:

     ngAfterViewInit() {
          setTimeout(() => {
              this.getLargeDataSet.subscribe(largeDataSet => {
                  this.dataSource.paginator = this.paginator;
                  this.dataSource.sort = this.sort;
                  this.dataSource.data = largeDataSet;
              });
          });
     }
    

    Supper fast, from 10+sec to 2sec :0

    0 讨论(0)
提交回复
热议问题