Angular 7 FormArray производительность рендеринга - PullRequest
0 голосов
/ 18 ноября 2018

В настоящее время я работаю над угловым компонентом для визуализации и изменения счета. Для редактирования элементов строки я использую FormGroup с FormArray элемента строки Forms:

lineItemForm: FormGroup = this.formBuilder.group({
    lineItems: this.formBuilder.array([])
});

Когда элементы строки задаются с помощью @ Input для компонента, для каждого элемента строки будет создаваться 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 строк. К сожалению, процесс рендеринга заблокирует пользовательский интерфейс на 10 секунд (!!!!!!), когда в счете будет около 30-40 строк, что абсолютно нелепо. </p>

Я почти уверен, что проблема заключается в рендеринге отдельных элементов формы. Когда я удаляю их и просто отображаю обычный текст, он будет отображаться намного быстрее.

Так есть ли какой-нибудь способ улучшения, который я могу сделать на моей стороне, или мне нужно ждать, пока угловая команда улучшит его? Или он никогда не будет пригоден для моего сценария, и мне придется искать какое-то другое решение?

Здесь - это ссылка на измерение производительности, созданное firefox dev-tools.

1 Ответ

0 голосов
/ 22 ноября 2018

После нескольких часов исследований и отладки я пришел к выводу, что проблемы с производительностью возникают из-за комбинации нескольких директив.

FormControl сам по себе не несет ответственности за задержку, которую я испытываю. Вместо этого я узнал, что вызовы Renderer (2) делают вещи очень медленными. В сочетании с некоторыми другими более или менее тяжелыми вычислениями это привело к такому поведению. Я просто не ожидал, что что-то вроде ".addClass" будет стоить около 400 мс во время рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...