Thank you very much Suni. I did get some improvement when doing some simplification, but you have gone way beyond what I had tried. So, I'll need to code this up and see what difference it makes. Excellent suggestions.
This is most definintely a case of my being too deep in the requirements/logic to see the simpler things. As a starting point I dropped in some timing code to work out how long things were taking. Turns out that each task is taking 120ms (on average) to complete, and with 250+ tasks, that translates to 30ish seconds. I think doing a simple ID selector rather than an attribute selector will help a great deal - if nothing else it'll clean up the code a little. I'll report back when I get these changes in place, though that may not be until tomorrow. Shawn Suni wrote: > There is a lot to optimize there. > > I'm sure most of the overhead comes from the each-loop. There is > propably other stuff to optimize too, but this looks like where you > could benefit the most. Lets quickly go through some problems: > >> $(".crewSchedule tr[id='" + cur.employee_id + "'] ." + lbl) > > Your selector string becomes something like ".crewSchedule > tr[id='35'] .1-Jan-2007". Selecting by attribute value is slow, and > you'll propably get a lot faster by simplifying your selector string > to "$('#' + cur.employee_id + ' .'+ lbl)" or "#35 .1-Jan-2007" > respectively. This lets jQuery find the tr-element straightforward by > it's id (which is the fastest possible selection since browsers give > us the native getElementById functionality). > >> var q = parseInt($(this).children(".qty").text()) + 1; >> $(this).children(".qty").text(q); >> $(this).children(".detail").html(task.summary(cur)); > > - Here you have many calls to $(this). While not terribly slow, it's > unnecessary. Each call wraps the tr-element inside a jQuery object, > which takes some time, and you do it three times. > > - You also search the rows children for elements with class .qty 2 > times, when one would be enough. > > Try this instead: > --- > var row_element = $(this); // Now we only need to wrap the tr- > element in the jQuery object once, and use that from then on > var qty_element = row_element.children(".qty"); // Same with > the .qty-element(s?) > var q = parseInt(qty_element.text() + 1); > qty_element.text(q); > row_element.children(".detail").html(task.summary(cur)); > --- > > These might give you some boost in performance. Just a few extra > notes: > > - Dom-access, selections and manipulations are _slow_. If you were to > iterate through the data and manipulate it while the data is inside a > pure javascript object or array it would be much faster. Going through > the DOM looking for elements and then updating them one by one is > terrible in performance compared to just looping over objects > properties and manipulating those. > > - Avoid selecting elements inside loops or other code that runs often. > If necessary, make sure the selector strings are as optimized as > possible. The best way is to always use an id-selector, as it is the > fastest. If at all possible, give unique id's to elements from server > side, or at least keep the DOM-tree inside such elements shallow for > quicker selections inside them. > > - Your script now propably goes through all the data and HTML before > giving anything to the user. You can greatly improve the perceived > speed of the script if you give the processed data to the user row by > row, as soon as it is ready. That way the user starts seeing stuff > immediately. The trick to achieve this is to use recursive functions > that use setTimeout with 0ms delays when calling themselves. This > frees the browsers rendering engine to draw the necessary stuff in > between the cycles, instead of waiting for the whole thing to finish. > > HTH