You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单组件内3个MatTable加载缓慢问题求助

解决Angular多MatTable加载缓慢的问题

看起来你遇到的核心问题是DOM冗余渲染和控件绑定错误导致的性能开销,哪怕总数据量不大,三个MatTable的无效初始化也会拖慢页面加载和切换速度。下面是针对性的解决方案:

一、核心问题分析

  1. [hidden]的DOM冗余:你用[hidden]隐藏未激活的表格,但这只是通过CSS隐藏元素,三个表格的DOM节点依然存在,Angular会初始化所有三个MatTable的排序、分页逻辑,产生不必要的计算开销。
  2. ViewChild绑定冲突:你只声明了一个MatPaginator和MatSort,但三个表格各有自己的分页器和排序组件,Angular无法正确绑定到每个表格的控件,导致内部逻辑混乱,额外增加渲染负担。
  3. 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;
    });
  }
}

三、额外优化建议

  1. 复用数据源(如果适用):如果三个表格展示的是相同数据,只是列或筛选条件不同,可以只创建一个MatTableDataSource,切换表格时更新displayedColumns或过滤条件,减少对象创建开销。
  2. 延迟初始化非激活表格:可以在切换到对应标签时再初始化该表格的数据源,初始加载时只处理第一个表格的数据,进一步加快首屏速度。

内容的提问来源于stack exchange,提问作者nhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:17:46