对组件宿主文档点击的巨大性能影响(Angular2)

Nam*_*mek 5 angular2-directives angular

所以我有一个组件的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!
  }
}
Run Code Online (Sandbox Code Playgroud)

我注意到这会极大地影响性能,每次单击document.

这是在 Chrome 中为序列制作的 JS CPU 配置文件:等待约 5 秒,单击,等待几秒钟并停止录制。点击是屏幕截图上巨大的绿色列:

单击无反应

我试过在这个组件甚至父组件上分离更改检测器,但这没有帮助。只需注释掉该行即可"(document: click)": "onClickOff($event)",解决问题。

可能是框架或使用不当的问题,但我不确定如何以更良好的实践方式对此或解决方法进行限定。

在这里

GitHub 问题在这里

Nam*_*mek 4

解决方案/解决方法

在 Angular 2.0.0(最终版)上,下面的代码将导致相同的性能问题:

ngAfterViewInit() {
    document.addEventListener('click', evt => this.evtClickHandler)
}
Run Code Online (Sandbox Code Playgroud)

在“区域”之外注册事件应该有所帮助:

constructor(zone: NgZone) {
}

ngAfterViewInit() {
    this.zone.runOutsideAngular(() => {
        document.addEventListener('click', evt => this.offClickHandler(evt))
    })
}
Run Code Online (Sandbox Code Playgroud)

解释

使用 Sortablejs 库时,我再次遇到了性能问题。在 Angular 最终版本之前情况并非如此,但由于在本机元素上注册事件而发生了一些变化。

对于 sortablejs 库,我这样做了:

this.sortedImages = Sortable.create(el, options)
Run Code Online (Sandbox Code Playgroud)

现在,拖动元素时性能非常糟糕:

在此输入图像描述

解决方案或解决方法如下:

this.zone.runOutsideAngular(() => {
  this.sortedImages = Sortable.create(el, options)
})
Run Code Online (Sandbox Code Playgroud)

this.zone注射到哪里@angular/core/NgZone。通过这种方式,库可以在 NgZone 之外注册事件侦听器。

我在 GitHub 上发布了一个关于这个问题的问题,但它被认为是我的编码错误,而不是 Angular 中的错误。然而,最新(RC - 最终之前)版本之间出现了一些变化。

所以这可能是一个错误或(最新)设计,但我对此没有确认。