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

加载10k+行至AG Grid透视表时页面无响应的前端优化咨询

AG Grid透视表前端性能优化方案(无需修改后端)

针对你遇到的透视表拖拽字段后页面无响应问题,结合你的代码场景,以下是纯前端的优化方案:

1. 限制透视维度数量,避免组合爆炸

当拖拽过多行/列字段时,透视后的行/列组合数会呈指数级增长,直接导致DOM渲染量过载。建议在交互层添加限制:

  • 限制行字段最多3个、列字段最多3个,超过时提示用户
  • 在updateTableColumns方法开头增加判断逻辑:
if (this.selectedRows.length > 3) {
  alert('行字段最多支持3个,过多会导致性能下降');
  return;
}
if (this.selectedColumns.length > 3) {
  alert('列字段最多支持3个,过多会导致性能下降');
  return;
}

2. 调整Grid渲染配置,最大化虚拟化效果

你的Grid配置已开启虚拟化,但部分设置削弱了效果,修改如下:

HTML模板修改

  • 移除min-height:150vh,改为固定视口高度,避免Grid高度异常导致虚拟化失效:
style="width: 100%; height: calc(100vh - 80px);"
  • 默认关闭所有组展开,减少初始渲染行数:
[groupDefaultExpanded]="0"
[pivotDefaultExpanded]="0"
  • 暂时关闭非必要的enableCharts功能,需要时再手动开启:
[enableCharts]="false"

3. 优化Grid更新逻辑,减少不必要重绘

你的updateTableColumns方法存在多次触发Grid重绘的操作,修改后合并更新步骤:

updateTableColumns() {
  if (!this.gridApi) return;

  if (this.selectedRows.length > 0) {
    // 维度数量限制逻辑...

    this.gridApi.showLoadingOverlay();
    this.updateColumnDefs();

    // 先设置行数据,再设置列定义,合并更新步骤
    if (this.filteredCaseInfoDispList?.length) {
      this.gridApi.setRowData(this.filteredCaseInfoDispList);
    }
    this.gridApi.setColumnDefs(this.colDefs);

    this.reportBuilderUtil.setLimitConfig(
      this.gridApi,
      this.selectedRows,
      this.selectedColumns
    );

    // 延迟处理Overlay,避免多次触发渲染
    setTimeout(() => {
      this.gridApi.hideOverlay();
      if (!this.filteredCaseInfoDispList?.length) {
        this.gridApi.showNoRowsOverlay();
      }
    }, 100);
  } else {
    this.gridApi.setColumnDefs([]);
    this.gridApi.showNoRowsOverlay();
  }

  // 移除不必要的markForCheck,Angular变更检测会自动处理
  // this.cdr.markForCheck();
}
  • 移除gridApi.refreshCells()调用:透视模式下,设置列定义和行数据后Grid会自动重新计算渲染,手动刷新会增加额外开销

4. 异步处理数据过滤,避免阻塞主线程

你的filterTableData是同步遍历全量数据,数据量大时会阻塞UI。改为分批异步处理:

filterTableData() {
  const totalData = this.caseInfoDispList;
  const filters = this.selectedFilters;
  const isMatchAll = this.isMatchAllFilters();
  const batchSize = 1000;
  let currentIndex = 0;
  this.filteredCaseInfoDispList = [];

  const processBatch = () => {
    const endIndex = Math.min(currentIndex + batchSize, totalData.length);
    const batch = totalData.slice(currentIndex, endIndex);
    const filteredBatch = batch.filter(item => {
      if (filters.length === 0) return true;
      const boolResult = filters.map(filter => this.reportBuilderUtil.isMatchFilter(filter, item));
      return isMatchAll ? boolResult.every(v => v) : boolResult.some(v => v);
    });
    this.filteredCaseInfoDispList = [...this.filteredCaseInfoDispList, ...filteredBatch];
    currentIndex = endIndex;

    if (currentIndex < totalData.length) {
      requestIdleCallback(processBatch);
    } else {
      this.gridApi?.setRowData(this.filteredCaseInfoDispList);
    }
  };

  requestIdleCallback(processBatch);
}
  • 利用requestIdleCallback在浏览器空闲时分批处理过滤,避免主线程阻塞

5. 减少不必要的变更检测

移除代码中多次调用的cdr.markForCheck():Angular的变更检测会自动监听colDefs、filteredCaseInfoDispList等绑定属性的变化,手动调用反而会增加额外的检测开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 08:13:13