Angular 由一个bug说起之一:List / Grid的性能问题

在angular中,MatTable构建简单,使用范围广。但某些时候会出现卡顿

卡顿情景:

1 **:**一次性请求太多的数据

2 **:**一次性渲染太多数据,这会花费CPU很多时间

3 **:**行内嵌套复杂的元素

4 **:**使用过多的ngStyle或者ngClass。或者一些额外的class

javascript 复制代码
        import { MatTableDataSource } from '@angular/material/table';    
...
        const data: IDemoRow[] = [];
        for (let i = 0; i < 8000; i++) {
            data.push({
                studentId: `studentId-${i + 1}`,
                name: `name-${i}`,
                className: `className-${i}`,
                age: i,
                address: `address-${i}`,
                studySubjects: [
                    'studySubjects-1',
                    'studySubjects-2',
                    'studySubjects-3',
                    'studySubjects-4',
                    'studySubjects-5',
                    'studySubjects-6',
                ],
                grade: 4
            });
        }
        this.dataSource = new MatTableDataSource(data);

第一次渲染会卡顿,拖动滚动条时会出现空白现象。

提升办法:

1 **:**分页

使用MatPaginator对数据进行分页

javascript 复制代码
    import { MatPaginator } from '@angular/material/paginator';
...
    @ViewChild(MatPaginator) paginator: MatPaginator;
...
    ngAfterViewInit() {
        this.dataSource.paginator = this.paginator;
    }
html 复制代码
<table mat-table [dataSource]="dataSource">
    ...
</table>
<mat-paginator
    [pageSizeOptions]="[13, 50, 200]"
    showFirstLastButtons>
</mat-paginator>

效果如下:

2:尽可能少用或不用ngStyle和 ngClass。无效的css及时清理。ngStyle不仅导致性能问题。还会使样式无法被覆盖。因此要慎用

css 复制代码
// less
.grade-background {
    background: #a1bcd6;
}
.grade-color {
    color: #37474f;
}

// html
<table mat-table [dataSource]="dataSource">
    ...
    <ng-container matColumnDef="grade">
        <th mat-header-cell *matHeaderCellDef class="class-unnecessary"> Grade </th>
        <td mat-cell *matCellDef="let element"
            class="table-cell grade-color class-unnecessary-test"
            [ngClass]="{'grade-background' : element.grade === 3}"
            [ngStyle]="{'color': '#DB5C5C'}">
            {{element.grade}}
        </td>
    </ng-container>
    ...
</table>

第一次渲染会卡顿,且ngStyle的值未被覆盖

3:使用trackBy,trackBy是angular提供的函数,来告诉angular怎么跟踪数组里的项目。这会减少不必要的DOM的删除和重建

html 复制代码
trackByFunction(index: number, row: IDemoRow): string {
    return row.studentId;
}

<table mat-table [dataSource]="dataSource"[trackBy]="trackByFunction">
    ...
</table>
<mat-paginator
    [pageSizeOptions]="[13, 50, 200]"
    showFirstLastButtons>
</mat-paginator>

4:但是对于更复杂的表的使用,比如分组管理数据。打开或者关闭某个组的时候,还要操作DOM,那么在以上几种方法的基础上可能还会卡顿

这时候需要利用interval分批操作DOM,能减少卡顿问题

javascript 复制代码
intervalH = window.setInterval(() => {
     ...
     if (...) {
        window.clearInterval(intervalH);
        intervalH = undefined;
     }
     ...
}, interval);

以上就是几种常用的优化方法。

相关推荐
crary,记忆20 小时前
Module Federation 和 Native Federation 的比较
前端·webpack·angular
crary,记忆2 天前
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
前端·webpack·angular·angular.js
crary,记忆2 天前
Angular中Webpack与ngx-build-plus 浅学
前端·webpack·angular·angular.js
crary,记忆4 天前
微前端 - Module Federation使用完整示例
前端·react·angular
crary,记忆6 天前
Angular报错:cann‘t bind to ngClass since it is‘t a known property of div
前端·javascript·angular·angular.js
Zhen (Evan) Wang7 天前
ABP-Book Store Application中文讲解 - Part 5: Authorization
c#·.net·angular
Zhen (Evan) Wang1 个月前
.NET 8 + Angular WebSocket 高并发性能优化
c#·.net·angular
百锦再2 个月前
React编程高级主题:错误处理(Error Handling)
前端·javascript·react.js·前端框架·vue·web·angular
KenkoTech2 个月前
Angular由一个bug说起之十五:自定义基于Overlay的Tooltip
angular
KenkoTech3 个月前
Angular由一个bug说起之十四:SCSS @import 警告与解决⽅案
angular