对Component的主机文档点击产生巨大的性能影响(Angular2)

时间:2016-09-22 15:25:58

标签: angular angular2-directives

所以我有 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!
  }
}

我注意到对性能造成巨大影响document上每次点击后都需要2-3秒的处理时间。

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

Single click on nothing reactive

我尝试在此组件或甚至父母上分离Change Detector,但这并没有帮助。只需注释掉"(document: click)": "onClickOff($event)",行即可解决问题。

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

Plunker here

GitHub issue here

1 个答案:

答案 0 :(得分:2)

解决方案/解决方法

在下面的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)

现在在拖动元素时导致了非常糟糕的性能:

enter image description here

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

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

注入this.zone @angular/core/NgZone。这样,库就会在NgZone之外注册事件监听器。

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

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