Angular 2 drag and drop directive extremely slow
Just went through some trouble with the same problem. Even with efficient ngFor
code, drag and drop can still be crazy slow if you have a large number of draggable items.
The trick for me was to make all drag and drop event listeners run outside of Angular with ngZone
, then make it run back in Angular when dropped. This makes Angular avoid checking for detection for every pixel you move the draggable item around.
Inject:
import { Directive, ElementRef, NgZone } from '@angular/core';
constructor(private el: ElementRef, private ngZone: NgZone) {}
Initializing:
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
el.addEventListener('dragenter', (e) => {
// do stuff with e or el
});
...
On drop:
el.addEventListener('drop', (e) => {
this.ngZone.run(() => {
console.log("dropped");
})
})
Thanks to everybody for this discussion. End up with simple solution which works like a charm:
constructor(private cd: ChangeDetectorRef) {
}
drag(event: DragEvent): void {
this.cd.detach();
// Begin the job (use event.dataTransfer)
}
allowDrop(event: DragEvent): void {
event.preventDefault();
}
drop(event: DragEvent): void {
event.preventDefault();
this.cd.reattach();
// Do the job
}