So I have 300 instantiations of a component which defines global click event listener through a host
property:
@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!
}
}
I noticed this hugely impacts performance, it takes about 2-3 seconds of processing after every click everywhere on a document
.
This is JS CPU profile made in Chrome for a sequence: wait ~5 seconds, click, wait few seconds and stop recording. The click is the huge green column on the screenshot:
I've tried detaching Change Detector on this component or even a parent but this didn't help. Simply commenting out the line "(document: click)": "onClickOff($event)",
fixes the problem.
May be an issue of the framework or bad usage but I'm not sure how to qualify this or workaround in a more good-practice-way.
Plunker here
GitHub issue here
On Angular 2.0.0 (final) code below will result in same performance issue:
ngAfterViewInit() {
document.addEventListener('click', evt => this.evtClickHandler)
}
registering event outside the "zone" should help:
constructor(zone: NgZone) {
}
ngAfterViewInit() {
this.zone.runOutsideAngular(() => {
document.addEventListener('click', evt => this.offClickHandler(evt))
})
}
Performance issue happened again to me using Sortablejs library. It wasn't the case before final version of Angular but something changed due to registering events on native elements.
For sortablejs library I did this:
this.sortedImages = Sortable.create(el, options)
which now resulted in really bad performance while dragging elements:
Solution or workaround goes like this:
this.zone.runOutsideAngular(() => {
this.sortedImages = Sortable.create(el, options)
})
where this.zone
is injected @angular/core/NgZone
. This way the library registers event listeners outside of NgZone.
I have posted an issue on GitHub about this problem but it was recognized as to be my error on coding, not bug in Angular. However, some changes appeared between latest (RC - before final) versions.
So this may be a bug or by (latest) design but I don't have confirmation on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With