Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI .sortable() call is slow when applies to thousands of elements

My issue is basically this - Applying jQuery UI Sortable to hundreds of elements on a page results in very slow page load -- need ideas on how to make it more efficient but since none of the answers solved my problem, I'm asking the question again.

Applying .sortable() on 300 elements (http://jsfiddle.net/LcgEL/) takes about 60ms. Applying it to thousands of element results in times approaching 250ms. This introduces a very noticeable delay that affects the user experience as it appears the application is laggy.

Is there any way to speed this up? Thanks!

JSFiddle link for the code - http://jsfiddle.net/LcgEL/
like image 651
Robin Rosicky Avatar asked Dec 05 '13 11:12

Robin Rosicky


3 Answers

If anyone stumbles on this page because they upgraded to 1.12.1 like me and hit the performance issue: Instead of rolling back to 1.11.4, find the _setHandleClassName function in the sortable widget (in my custom download around line #5300 in jquery-ui.js) and change:

$.each( this.items, function() {
    that._addClass(
        this.instance.options.handle ?
        this.item.find( this.instance.options.handle ) :
        this.item,
        "ui-sortable-handle"
    );
});

To:

$.each( this.items, function() {
    (this.instance.options.handle 
     ? this.item.find( this.instance.options.handle ) 
     : this.item
    ).addClass('ui-sortable-handle');
});

Like it was in the previous version.

For my case this sped up the initialization of a sortable list of 700 items from ~20 seconds to some milliseconds. o_O

Do note: While I haven't seen any issues yet using this approach for my page, it hasn't been thoroughly tested due to lack of time.

like image 79
Ernst Avatar answered Nov 12 '22 16:11

Ernst


a tough one, I had a similar problem with hundreds of images that needed to be draggable. and initialization just took too much time

I was able to solve it by lazy instantiation upon mouseenter, it works great, and the user experience is not changed

Here is how it could be done with sortable: (http://jsfiddle.net/q8ND4/3/)

var $sortable1 = $( "#sortable1" ).sortable({
  connectWith: ".connectedSortable",
  items: ".sorting-initialize" // only insert element with class sorting-initialize
});
$sortable1.find(".ui-state-default").one("mouseenter",function(){
  $(this).addClass("sorting-initialize");
  $sortable1.sortable('refresh');
});

In your example it decreases the time from 30ms to 8ms.

Another improvement: The next step will be to move the mouseenter handler binding to the point in code when you append these <li> to the list (if this is done via js on the client side)

like image 20
ekeren Avatar answered Nov 12 '22 17:11

ekeren


You should roll back your version of jQuery UI to version 1.11.4 https://jqueryui.com/download/all/

After struggling with this for a few days that was the only thing that helped me. I have about 800 entries being sorted between 6 lists. Using UI v1.12.1 my page was taking about 20 seconds to load. After switching to v1.11.4 my page load time was closer to 5 seconds.

I tried the solution by ekeren which partially worked, but elements that hadn't been initialized weren't in the 'sorting order' so you could only interact with elements that had already been hovered over.

like image 43
E Benzle Avatar answered Nov 12 '22 16:11

E Benzle