supraniti/Lean-Mean-Drag-and-Drop

How does this compare to other libraries?

Opened this issue · 9 comments

Hey, cool library. Heads up, I'll be creating a few issues :).

How does this compare to other libraries, like dragula for example, when it comes to performance / efficiency? I'm finding it hard to evaluate that (desktop & mobile).

I did notice that if I turn on "paint flashing" in Chrome's dev tools, there are lot more (needless?) repaints with this library versus Dragula.

I wonder how this affects performance on smaller / less powerful machines.

Thanks for the feedback 👍
There are quite a few differences between LMDD and other d&d libraries. The most known libraries are probably jQuery sortable UI, dragula, and Sortable.
LMDD was designed to handle a specific use case: 'nested sortable lists' - dragging one sortable list into another one. It is possible to achieve this with other libraries but it will take some effort to implement and animating the transitions is practically impossible.
The difficulty comes from the need to move HTML element between two parent nodes.
To overcome this problem when dealing with nested structures, and provide smooth transitions (of all elements in scope) LMDD is creating a clone of the entire scope. What you see while dragging is a clone of the original dom structure, and every element is positioned relatively and 'follows' the original element location and dimensions.
This is an expensive process so I guess LMDD consumes more CPU comparing to other libraries.
But this happens only while dragging.
Before/After the drag event, there is practically zero CPU and memory usage. Other d&d libraries creates 'sortable' objects and add a bunch of event listeners that consumes memory even when no dragging happens. LMDD creates only one event listener, and does not store anything permanent in memory so it keeps your app light and responsive no matter how many draggable items and lists you want to handle.
Given the fact that drag operations are usually short (no more than a few seconds) I think this approach is much more efficient. Especially when considering the benefits (much slicker user experience and easier implementation).

Thanks for the info.

What you see while dragging is a clone of the original dom structure, and every element is positioned relatively and 'follows' the original element location and dimensions.

This works fine for my simple example, but will this work even if I use complex layout stuff inside my items? E.g. using flexbox. If no, would adding lmdd-block fix that?

To overcome this problem when dealing with nested structures, and provide smooth transitions (of all elements in scope) LMDD is creating a clone of the entire scope. What you see while dragging is a clone of the original dom structure, and every element is positioned relatively and 'follows' the original element location and dimensions.

OK I getcha. Maybe there is some needless work being done though but I could be wrong. Based on what I saw from the paint flashing, if I click down on an item in container A (and without leaving go), drag it over container B, every item in container B is re/painted, if I drag back to A, everything in A is repainted, if I drag to back to B again, everything in B is repainted again even though nothing has changed.

This is an expensive process so I guess LMDD consumes more CPU comparing to other libraries.

I won't have nested structures. At most I'll have multiple sibling lists and I want to drag between them. Is there anything beyond adding lmdd-block to my items which could make it more efficient? This could even include adding more config options which if set appropriately will result in less work being done / a simpler approach in places.

Before/After the drag event, there is practically zero CPU and memory usage. Other d&d libraries creates 'sortable' objects and add a bunch of event listeners that consumes memory even when no dragging happens. LMDD creates only one event listener, and does not store anything permanent in memory so it keeps your app light and responsive no matter how many draggable items and lists you want to handle.

Great.

Confirmed that flexbox is OK. Stuff like display: block; is added to the item when being dragged so once you've display: flex !important; it'll be fine (although I guess it would be nice if we didn't have to have !important at all).

Hi, am interested how it behaves with css grids? In regard that flexbox is OK. Currently am trying sortablejs, and am having weird results lol you can clearly see in the video, my guess is that css grids are the cause
http://recordit.co/Plzkt0Fv8o

as you can see, dragging an element around, does change the html structure.
but css grid layouts are based on css... meaning - the visual location of an element does not necessarily aligns with the html structure.
further more, css grid layout does not support transitions - so when you replace one element with another via drag an drop operation it may look as nothing changed at all.
any particular reason using css grids for your app?

yes it does, but its kinda not sure about where the drop area is, so sortable-chosen keeps jumping between elements, like its guessing where the drop area is in the grid, so sometimes it works sometimes it doesn't, that leads to, that if you want to drop element in big css grid area with 6 cells, works only if you drag element and drop it into top 2 or 4 cells, trying to drop element into bottom 2 cells it drops randomly onto other grid area, grid area that is just 1 cell is bigger problem in that it rarely works, keep in mind that this is using sortable js, am going to try lmdd now and report back.

Regarding transitions its fine i dont need them in this case, and am using css grids because i need complex tile kinda layouts as placeholders that will display images, with flexbox i had problems with height and ratios and positioning. As you saw in the video i need every cell to fit image (whatever size it may be) full height and width, using object fit helps here also, the problem is when you add or remove element(cell) i need different layout, so for example if there are 8 images i need at least 17 different templates, then when there are 7 another 17 different templates and so on, now you can imagine using css grid areas this is sooooo nice and easy to do, not to mention maintainable and scaleble, if i need more templates just add them, and by using that kinda ascii syntax, just looking at it you can see how the layout looks like eg.
grid-template-areas: "a a b b c c" "a a d d c c" "a a g h e f";

So now, i need them to be draggable too lol :) so i can drag grid area "a" to grid area "f" and so on

Ok am getting [Vue warn]: Error in mounted hook: "TypeError: el is null" am using Vue js 2 with webpack simple, i dont know what the problem is, am also using vuex so maybe that is the cause, but idk. Structure is simple, with App.vue and Book.vue as component, i tried mounted and method in both components but keep getting this error message, so idk, maybe i try later again and figure what the problem is, in lmdd.js on line number 674 with msg el is null

hi )
can you post a reference to your code? jsfiddle / codepen