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

Angular CDK 15表格如何结合虚拟滚动组件优化性能?

Angular 15 CDK Table 结合虚拟滚动优化性能

你的问题在于直接把整个cdk-table塞进cdk-virtual-scroll-viewport里,两者并不会自动联动——cdk-table会自行渲染所有行,完全不受虚拟滚动容器的控制。要实现两者结合,你需要调整结构,用*cdkVirtualFor替代*cdkRowDef来渲染行,让虚拟滚动容器直接管理行的渲染数量。

正确实现步骤及代码示例

  1. 保留表格基本结构,但移除cdk-table的[dataSource]绑定,行的渲染将由虚拟滚动控制
  2. 在cdk-virtual-scroll-viewport内部用*cdkVirtualFor遍历数据渲染行
  3. 确保itemSize与实际行高一致,这是虚拟滚动计算可视区域的关键
  4. 配合trackBy函数减少不必要的DOM重渲染
<!-- 虚拟滚动容器 -->
<cdk-virtual-scroll-viewport appendOnly itemSize="50" class="example-viewport">
  <table class="table-with-tree-wrapper">
    <!-- 表头 -->
    <thead>
      <tr>
        <!-- 对应你的displayedColumns列定义 -->
        <th *ngFor="let col of displayedColumns">{{col}}</th>
      </tr>
    </thead>
    <tbody>
      <!-- 用*cdkVirtualFor渲染行,替代原来的*cdkRowDef -->
      <tr
        *cdkVirtualFor="let row of dataSource; trackBy: identifyRows"
        [class.table-row-hover]="hoverOnRow"
        [class.table-row-selected]="row?.element?.selected"
      >
        <!-- 根据列名渲染对应数据 -->
        <td *ngFor="let col of displayedColumns">
          {{row[col]}}
        </td>
      </tr>
    </tbody>
  </table>
</cdk-virtual-scroll-viewport>

额外注意事项

  • 若需要表头固定,直接给<thead>添加CSS样式即可:position: sticky; top: 0; background: #fff;,无需依赖cdk-header-row的sticky属性
  • appendOnly属性仅适合数据只会追加的场景(比如无限滚动加载),如果数据会频繁更新,建议移除该属性
  • 必须给虚拟滚动容器设置固定高度,否则无法计算可视区域:
.example-viewport {
  height: 500px; /* 根据需求调整高度 */
  overflow: auto;
}

保留CDK Table列定义的方案

如果你想复用cdk-table的列定义能力(比如cdkColumnDef),可以将虚拟滚动容器作为表格的行容器:

<table cdk-table>
  <!-- 列定义 -->
  <ng-container *ngFor="let col of displayedColumns" [cdkColumnDef]="col">
    <th cdk-header-cell *cdkHeaderCellDef>{{col}}</th>
    <td cdk-cell *cdkCellDef="let row">{{row[col]}}</td>
  </ng-container>

  <!-- 固定表头 -->
  <tr cdk-header-row *cdkHeaderRowDef="displayedColumns; sticky: true"></tr>

  <!-- 虚拟滚动行容器 -->
  <cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
    <tr
      cdk-row
      *cdkVirtualFor="let row of dataSource; trackBy: identifyRows"
      [class.table-row-hover]="hoverOnRow"
      [class.table-row-selected]="row?.element?.selected"
      [cdkRowDef]="displayedColumns"
    ></tr>
  </cdk-virtual-scroll-viewport>
</table>

这种方案既保留了cdk-table的列定义逻辑,又让虚拟滚动控制行的渲染数量,适合需要复杂列配置的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:26:08