单组件内3个MatTable加载缓慢问题求助
解决Angular多MatTable加载缓慢的问题
看起来你遇到的核心问题是DOM冗余渲染和控件绑定错误导致的性能开销,哪怕总数据量不大,三个MatTable的无效初始化也会拖慢页面加载和切换速度。下面是针对性的解决方案:
一、核心问题分析
[hidden]的DOM冗余:你用[hidden]隐藏未激活的表格,但这只是通过CSS隐藏元素,三个表格的DOM节点依然存在,Angular会初始化所有三个MatTable的排序、分页逻辑,产生不必要的计算开销。- ViewChild绑定冲突:你只声明了一个
MatPaginator和MatSort,但三个表格各有自己的分页器和排序组件,Angular无法正确绑定到每个表格的控件,导致内部逻辑混乱,额外增加渲染负担。 - TS代码笔误:你重复初始化了
dataSource2三次,漏掉了dataSource3,虽然不影响功能,但属于冗余代码,可能引发潜在问题。
二、分步解决方案
1. 替换[hidden]为*ngIf
*ngIf会在条件不满足时完全移除DOM节点,只有当前激活的表格才会被创建和初始化,大幅减少页面加载时的工作量:
<div id="div1" *ngIf="div1===1 && div2===0 && div3===0"> <table mat-table [dataSource]="dataSource1" #sort1 matSort> <!-- table 1 列定义 --> </table> <mat-paginator #paginator1 [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator> </div> <div id="div2" *ngIf="div1===0 && div2===1 && div3===0"> <table mat-table [dataSource]="dataSource2" #sort2 matSort> <!-- table 2 列定义 --> </table> <mat-paginator #paginator2 [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator> </div> <div id="div3" *ngIf="div1===0 && div2===0 && div3===1"> <table mat-table [dataSource]="dataSource3" #sort3 matSort> <!-- table 3 列定义 --> </table> <mat-paginator #paginator3 [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator> </div>
2. 修正ViewChild绑定逻辑
给每个分页器和排序器添加模板引用变量,分别绑定到对应的表格数据源:
import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { AppService } from './app.service'; @Component({ selector: 'app-my-component', templateUrl: './my-component.component.html', styleUrls: ['./my-component.component.css'], // 可选:启用OnPush变更检测,进一步提升性能 changeDetection: ChangeDetectionStrategy.OnPush }) export class MyComponent implements OnInit { // 分别获取每个表格的分页器和排序器 @ViewChild('paginator1', { static: true }) paginator1: MatPaginator; @ViewChild('sort1', { static: true }) sort1: MatSort; @ViewChild('paginator2', { static: true }) paginator2: MatPaginator; @ViewChild('sort2', { static: true }) sort2: MatSort; @ViewChild('paginator3', { static: true }) paginator3: MatPaginator; @ViewChild('sort3', { static: true }) sort3: MatSort; resultdata: any[]; dataSource1: MatTableDataSource<any>; dataSource2: MatTableDataSource<any>; dataSource3: MatTableDataSource<any>; // 每个表格可以独立定义列(如果需要) displayedColumns1 = ['col1','col2']; displayedColumns2 = ['col1','col2']; displayedColumns3 = ['col1','col2']; div1 = 1; div2 = 0; div3 = 0; constructor(private _servcall: AppService) { } ngOnInit() { this._servcall.getdatafromapi().subscribe(result => { this.resultdata = result; // 绑定第一个表格的数据源 this.dataSource1 = new MatTableDataSource(this.resultdata); this.dataSource1.paginator = this.paginator1; this.dataSource1.sort = this.sort1; // 绑定第二个表格的数据源(修正之前的笔误) this.dataSource2 = new MatTableDataSource(this.resultdata); this.dataSource2.paginator = this.paginator2; this.dataSource2.sort = this.sort2; // 绑定第三个表格的数据源 this.dataSource3 = new MatTableDataSource(this.resultdata); this.dataSource3.paginator = this.paginator3; this.dataSource3.sort = this.sort3; }); } }
三、额外优化建议
- 复用数据源(如果适用):如果三个表格展示的是相同数据,只是列或筛选条件不同,可以只创建一个
MatTableDataSource,切换表格时更新displayedColumns或过滤条件,减少对象创建开销。 - 延迟初始化非激活表格:可以在切换到对应标签时再初始化该表格的数据源,初始加载时只处理第一个表格的数据,进一步加快首屏速度。
内容的提问来源于stack exchange,提问作者nhi
相关产品推荐
相关产品推荐

