Angular-tree-component: Drag & Drop painfully slow performance

Created on 11 Jul 2017  Â·  20Comments  Â·  Source: CirclonGroup/angular-tree-component

Hi,

iam using the tree with arround 20 nodes and a depth up to 3 nodes. Drag & Drop feels impossible, draging a node somewhere takes about 10 seconds until things settle. I tested this with angular 4.2.6 as well as some previous versions in develop (straight) and production (aot compiled).

I tried to remove all unnecessary code down to a minimum, even without a custom template and only simple options, did not help.

this flame für the develop build looks like:
image

production:
image

Most helpful comment

I maintain a fork of this project that has a few additional features that I need for a private project, and I ran into this issue. It wasn't hard to diagnose the problem, but it was significantly harder to implement a solution.

Symptoms: In large Angular applications, the drag and drop for the tree nodes is horrendously slow, even if the tree itself is very small.

Problem: There are six different events related to drag and drop, fired constantly as you drag a node around, and each one triggers a full Angular change detection cycle. If the Angular application is large or not well-optimized, the browser is left spinning its wheels running CDs left and right and doesn't have the resources to keep up with all of the drag events.

My Solution: I reworked the treeDrag and treeDrop directives to make the more common/invasive drag+drop events run outside of Angular, so that they don't trigger change detection. I left the dragstart, dragend, and drop events in, because they only fire once for each drag+drop, but I fired the drag, dragover, dragenter, and dragleave events outside of Angular. This completely fixes the performance issue, but if the user tries to handle any of those four events they may be surprised when the page isn't immediately updated because the handlers are invoked outside of the standard change detection cycle. This is good enough for my use case, because I don't use those events anyway; but the solution isn't ideal because if somebody in the future tried to use the component without knowing about these peculiarities they could potentially spend hours trying to figure out why some events trigger change detection and others do not.

If the maintainers of this repository are interested in this solution, I will create a PR with this fix. Otherwise, here is a link to the commit on my fork that fixed this issue (for reference).

All 20 comments

Very strange, do you feel that also in the demo example?
Have you tried using enableProdMode()?

Yes, we are running an angular/cli production build too, performance is better but far from usable

@kferstl do you get this behaviour with the demo as well?
I've tried with hundreds of nodes and didn't experience any lagging at all.
Do you have any listener running on the drag event?

I have the same painfully performance too, when dnd on a large tree (useVirtualScroll is true)

Can you please reproduce in the plunkr please:
https://plnkr.co/edit/u5fMmaM14rJ0aqG3k240?p=preview?

+1

I maintain a fork of this project that has a few additional features that I need for a private project, and I ran into this issue. It wasn't hard to diagnose the problem, but it was significantly harder to implement a solution.

Symptoms: In large Angular applications, the drag and drop for the tree nodes is horrendously slow, even if the tree itself is very small.

Problem: There are six different events related to drag and drop, fired constantly as you drag a node around, and each one triggers a full Angular change detection cycle. If the Angular application is large or not well-optimized, the browser is left spinning its wheels running CDs left and right and doesn't have the resources to keep up with all of the drag events.

My Solution: I reworked the treeDrag and treeDrop directives to make the more common/invasive drag+drop events run outside of Angular, so that they don't trigger change detection. I left the dragstart, dragend, and drop events in, because they only fire once for each drag+drop, but I fired the drag, dragover, dragenter, and dragleave events outside of Angular. This completely fixes the performance issue, but if the user tries to handle any of those four events they may be surprised when the page isn't immediately updated because the handlers are invoked outside of the standard change detection cycle. This is good enough for my use case, because I don't use those events anyway; but the solution isn't ideal because if somebody in the future tried to use the component without knowing about these peculiarities they could potentially spend hours trying to figure out why some events trigger change detection and others do not.

If the maintainers of this repository are interested in this solution, I will create a PR with this fix. Otherwise, here is a link to the commit on my fork that fixed this issue (for reference).

@aboveyou00 hi, we ended up building our own tree. We used the dragula library, it took us about one day to build a pretty awesome tree :-)
https://github.com/valor-software/ng2-dragula

@aboveyou00 can you make a PR for that? That is likely the proper way to fix this issue.

Nevermind, I went ahead and did it :smile:

@aboveyou00 - would love to see a PR.
BTW, there's another PR that aims to solve this issue by moving events outside of Angular: https://github.com/500tech/angular-tree-component/pull/587

@mtraynham, @adamkleingit: sorry I didn't do that myself. I was busy getting ready for GDC, but even so I should have responded.

+1 on the PR, BTW

@kferstl: can you checkout master and confirm that this fixes the speed issue you were seeing?

I will publish a new version soon.
I'm trying to replace the entire test infrastructure to testcafe because
protractor was getting really annoying and flaky.
Tests kept failing in CI even though they passed on local machine.

On Thu, Mar 22, 2018 at 8:21 AM, Brandon notifications@github.com wrote:

@kferstl https://github.com/kferstl: can you checkout master and
confirm that this fixes the speed issue you were seeing?

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/500tech/angular-tree-component/issues/352#issuecomment-375192525,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACUsQwSTLDiesT9MwBQvSRQRQkDGZQzoks5tg0LXgaJpZM4OUW3F
.

--

Adam Klein
Chief Technology Officer

Tel. +972-52-7475633 <+972527475633>
Web 500tech.com http://www.500tech.com/ | github.com/500tech |
@adamklein500
http://twitter.com/adamklein500

Can you try with 7.1.0?

just tried it out and the performance with version 7.1.0 is MUCH better, had the same problem that it was not useable, but now... big thx for that!

Awesome

@aboveyou00 hi, we ended up building our own tree. We used the dragula library, it took us about one day to build a pretty awesome tree :-)
https://github.com/valor-software/ng2-dragula

it would be nice if you can explain more based on my knowledge dragula does not support nested forms

I spent serveral days grappling with the drag and drop slowness. I tried several offered solutions with no luck. I was finally able to solve the issue by replacing the Angular (dragOver)="function()" with the native HTML ondragover="preventDefault()". Doing so prevented Angular change detection from firing while dragging.

Kudos to @leviathanbadger for explaining it so well.
Another approach I used after reading his explanation was to leave the (drag)="...", (drop)="..." but switch the dragover part to pure js since I only wanted to do that: ondragover="event.preventDefault()"

draggable="true" is also used like that.

When you have a custom template, how are you able to resolve this issue?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chpasha picture chpasha  Â·  5Comments

salilbajaj picture salilbajaj  Â·  4Comments

JanSchuermannPH picture JanSchuermannPH  Â·  4Comments

anoop-chauhan picture anoop-chauhan  Â·  3Comments

filipemansano picture filipemansano  Â·  5Comments