ngClass на многих элементах делает сайт очень медленным - PullRequest
0 голосов
/ 18 октября 2018

В настоящее время я работаю в виде дерева в своем приложении Angular 6, которое я получил (вложенный и все остальное).Одна из проблем, с которыми я сталкиваюсь, заключается в том, что когда на моей странице много элементов (несколько тысяч) и на всех из них есть [ngClass] (для отображения разных цветов в зависимости от выбранного узла), страница имеет тенденцию зависать.Я создал StackBlitz, чтобы показать мою проблему: https://stackblitz.com/edit/angular-atveai

Чтобы проверить это, просто нажмите и удерживайте клавиши со стрелками вверх / вниз на правом экране вывода.Это должно быть очень медленно.Если вы установите в цикле только 100 элементов вместо 10000, он будет работать безупречно (потому что элементов меньше).

Чтобы перехватить событие keydown (которое я хочу в моем документе), я делаю это:

@Component({
  host: {
    '(document:keydown)': 'handleKeyboardEvent($event)'
  }
})

Это вызывает handleKeyboardEvent() с объектом $event.

В файле HTML у меня есть очень простой *ngFor, где каждый элемент имеет [ngClass]="GetClass(item)".В основном это возвращает объект, который содержит все классы, которые должны быть применены.В моем случае, если выбранный узел равен элементу, он устанавливает obj["selected"] = true, так что один элемент получит класс selected.

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

Моя страница может легко иметь от 5000 до 10000 узлов (что-то, что мы действительно не хотим менять, если есть способ это исправить).Тем не менее, количество корневых узлов, вероятно, составляет от 10 до 30. Многие узлы вложены как дочерние (в основном 99% из них вложенные).

Я бы подумал, чтобы [ngClass] не слушализменяется, если родительский узел NOT раскрыт.Не развернуто = не отображается на странице в любом случае.

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

1 Ответ

0 голосов
/ 18 октября 2018

Итак, я понял вроде работает так:

1) Использовать обнаружение изменений OnPush

@Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      host: {
        '(document:keydown)': 'handleKeyboardEvent($event)'
      },
      changeDetection: ChangeDetectionStrategy.OnPush
    })

2) Использовать интерполяцию шаблона вместо вызовов функций

<span class="{{item.state === 'failed' ? 'failed' : 'completed'}} {{item.ordering === selected ? 'selected' : ''}}">{{item.name}}</span>

Он работает быстро с 5000 строками, но все еще медленно с 10000. К сожалению, лучшее, что я мог сделать.

https://stackblitz.com/edit/angular-1sg1mh?file=src%2Fapp%2Fapp.component.ts

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