angular - Angular 7 FormArray 渲染性能
问题描述
我目前正在研究一个角度组件来呈现和修改发票。要编辑行项目,我使用了带有行项目表单的 FormArray 的 FormGroup:
lineItemForm: FormGroup = this.formBuilder.group({
lineItems: this.formBuilder.array([])
});
当通过@Input为组件设置 lineitem 时,将为每个 lineitem 创建一个FormGroup 。
set lineItems(lineItems: InvoiceLineItem[]) {
this.lineItemForm.controls['lineItems'] = this.formBuilder.array(
lineItems.map(lineItem => {
return this.createLineItemForm(lineItem);
})
);
this._lineItems = lineItems;
}
private createLineItemForm(lineItem: InvoiceLineItem): FormGroup {
return this.formBuilder.group({
_id: [lineItem._id],
number: [lineItem.number],
amount: [lineItem.amount, Validators.compose([Validators.required, NumberValidator.validateNumber(2)])],
title: [lineItem.title],
netprice: [lineItem.netprice, Validators.compose([Validators.required, PriceValidator.validatePrice()])],
netpriceTotal: [lineItem.netpriceTotal, Validators.compose([Validators.required, PriceValidator.validatePrice()])],
grosspriceTotal: [lineItem.grosspriceTotal],
taxrate: [lineItem.taxrate, Validators.compose([Validators.required, IntegerValidator.validateInteger()])],
taxTotal: [lineItem.taxTotal],
from: [lineItem.from, DateValidator.validateDate('DD.MM.YYYY HH:mm')],
to: [lineItem.to, DateValidator.validateDate('DD.MM.YYYY HH:mm')],
pageIndex: [],
rowOrder: []
});
}
模板代码如下所示(简化):
<div formArrayName="lineItems"
*ngFor="let lineItem of lineItemForm.controls['lineItems'].controls; trackBy:getLineItemIdentity; let i = index; let even = odd">
<div *ngFor="let column of alwaysVisibleColumns; trackBy:getColumnIdentity; let col = index; let f = first; let l = last;"
[formGroupName]="i">
<div [formControlName]="column.field" some-custom-directives...></div>
</div>
</div>
我知道我使用 div 作为formControls(有自定义指令将它们用作内容可编辑的输入)
当有 < 10 个 lineitem 时,没有任何问题。不幸的是,当发票上有大约 30-40 个项目时,渲染过程将阻塞 UI 大约 10 秒(!!!!!!)——这绝对是荒谬的。
我很确定问题出在各个 formControls 的渲染上。当我删除它们并只显示纯文本时,它的渲染速度会快得多。
那么我有什么方法可以改进,还是我必须等到 Angular 团队改进它?还是它永远无法用于我的场景,我必须找出其他解决方案?
这是 Firefox 开发工具创建的性能测量链接。
解决方案
经过几个小时的调查和调试,我得出结论,性能问题来自多个指令的组合。
FormControl 本身不对我遇到的延迟负责。相反,我发现对 Renderer(2) 的调用使事情变得非常缓慢。与其他一些或多或少的繁重计算配对导致了这种行为。我只是没想到像“.addClass”这样的东西在渲染时间上会花费大约 400 毫秒。
推荐阅读
- r - 有没有办法在 R 中使用 dplyr 根据另一个列的值创建一个新列?
- android - Android 错误:特定代码块中的“不是语句”
- react-admin - 我可以更改每条路线的 react-admin 布局吗?
- fortran - 赋值后的实际值与实际表达式不同
- angular - 从 OL OSM 中的图层源获取中心点
- python - C++ 和 Boost.Python - 如何向 python 公开变量并在循环中更新它?
- python - 如何让 conda 知道我的包的数据和配置文件在哪里
- php - PHP循环遍历多维数组
- api - Hotstar API 使用有状态架构吗?即使没有登录,它如何跟踪用户?
- python - 在递归中使用全局变量