Проблема производительности с вложенными циклами * ngFor, используемыми для отображения иерархических данных - PullRequest
0 голосов
/ 29 сентября 2019

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

  1. * ngFor - 10 панелей расширения (уровень 1) для каждого элемента
  2. * ngДля списка 10 элементов (уровень 2) для отображения содержимого
  3. * ngДля 5 элементов (уровень 3) 5 переключателей кнопок и 2 элемента управления

Чтобы избежать загрузки всех данных, я устанавливаю коллекцию для 2nd * ngFor, основываясь на текущей открытой панели с уровня 1.

Вся страница очень медленная, когда я расширяю панель или когда япытаясь нажать кнопку переключения.Примечание: я не изменяю коллекции с этими действиями.

Для отладки я помещаю функцию в каждый ngFor, чтобы возвращать коллекции.Я видел, что каждый раз, когда я нажимаю кнопку переключения, angular многократно повторяет все итерации во всех директивах * ngFor.

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

Пример кода, воспроизводящего проблему на stackblitz !

Ответы [ 2 ]

1 голос
/ 29 сентября 2019

Вы можете немного улучшить производительность, используя переменную «index» и сделать «content» видимым, только если это значение выбрано в соответствии

<!--I put the *ngFor in the own mat-expansion-panel-->
<mat-expansion-panel 
          *ngFor="let itemLevel1 of this.rootItem.children;let i=index"
          [expanded]="false" 
           <!--see that pass, itemLevel1 and "i"-->
          (opened)="onOpenLevel1Panel(itemLevel1,i)">
    <mat-expansion-panel-header>
      ...
    </mat-expansion-panel-header>   
    <ng-container *ngIf="i==index" >  
         <div *ngFor="let itemLevel2 of this.selectedItemChildren;">
            ....
         </div>
    </ng-container>
<mat-expansion-panel>

В OpenLevel1Panel мы используем переменную index

  index:number=-1;

  onOpenLevel1Panel(selectedItem: Item,index:number): void {
    this.selectedItemChildren = selectedItem.children;
    this.index=index;
  }

Далее, я думаю, что "опции" - это реальная причина для замедления приложения

0 голосов
/ 29 сентября 2019

Вы указали на реальную проблему, вложенные данные .* ngДля создания простых плоских итераций.Отсюда вы можете попытаться объединить некоторые приемы и приемы:

  1. Оптимизируйте рендеринг с помощью 'trackby'.Это поможет, но не может решить эту проблему.
  2. Попробуйте сгладить данные, используя подход «умный тупой», см. этот пример
  3. ленивый обработчик каждого уровня отдельно, Вы даже можете обрабатывать любой рекурсивный глубокий уровень (щелчок открывает новый уровень)
  4. Оптимизация рендеринга с использованием виртуальная прокрутка , это не будет отображать невидимые данные, что хорошо для длинных списков.
...