Огромное влияние на производительность при щелчке основного документа компонента (Angular2)

Таким образом, у меня есть 300 экземпляров компонента, который определяет глобальный слушатель события щелчка через host имущество:

@Component({
  selector: 'value-edit',
  template: ``,
  host: {
    "(document: click)": "onClickOff($event)",
  },
  changeDetection: ChangeDetectionStrategy.OnPush
)
export class ValueEditComponent {
  onClickOff(globalEvent) {
    // to make sure it doesn't affect performance we keep it EMPTY!
  }
}

Я заметил, что это сильно влияет на производительность, занимает около 2-3 секунд обработки после каждого нажатия на document,

Это профиль процессора JS, созданный в Chrome для последовательности: подождите ~5 секунд, нажмите, подождите несколько секунд и остановите запись. Клик - огромный зеленый столбец на скриншоте:

Один клик на ничего не реагирует

Я пытался отключить детектор изменений на этом компоненте или даже родительском, но это не помогло. Просто комментируя строку "(document: click)": "onClickOff($event)", устраняет проблему

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

Плункер здесь

GitHub выдает здесь

1 ответ

Решение / обходной путь

На Angular 2.0.0 (окончательный) код ниже приведет к той же проблеме производительности:

ngAfterViewInit() {
    document.addEventListener('click', evt => this.evtClickHandler)
}

Регистрация события за пределами "зоны" должна помочь:

constructor(zone: NgZone) {
}

ngAfterViewInit() {
    this.zone.runOutsideAngular(() => {
        document.addEventListener('click', evt => this.offClickHandler(evt))
    })
}

объяснение

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

Для библиотеки sortablejs я сделал это:

this.sortedImages = Sortable.create(el, options)

что теперь привело к очень плохой производительности при перетаскивании элементов:

Решение или обходной путь идет так:

this.zone.runOutsideAngular(() => {
  this.sortedImages = Sortable.create(el, options)
})

где this.zone вводится @angular/core/NgZone, Таким образом, библиотека регистрирует прослушиватели событий за пределами NgZone.

Я опубликовал на GitHub вопрос об этой проблеме, но она была признана моей ошибкой при кодировании, а не ошибкой в ​​Angular. Тем не менее, некоторые изменения появились между последними (RC - до финальной) версии.

Так что это может быть ошибка или (последний) дизайн, но у меня нет подтверждения на это.

Другие вопросы по тегам