I was able to implement some of the changes you recommended.  I did away 
with the .each() bit, switched to using tr#ID instead of tr[id=], and 
stored the commonly used bits in temporary variables (one search then, 
multiple references).  The end result is that the code is a lot cleaner 
looking, but performance wise still about the same.

You suggested doing the manipulations in memory.  I'm not clear how I 
might do this.  Would doing something like
var theTable = $("#mytable").clone() be a good starting point?  Then I 
can do the manipulations on $(theTable), and later do a 
$("#mytable").replace(theTable).  Does that make sense?  Otherwise, I'm 
not sure how to get the existing table into memory and avoid rendering 
updates for each of the changes.

Other than that, I think my only real option is to change what data I'm 
getting back from the server.  Instead of creating the rows on the fly 
like I currently am, I *could* have the server side code return an 
object that contains the row string already.  Then instead of doing 250+ 
task placements, I would just need to replace 50ish rows which should be 
a LOT faster I think.  But that's just moving the processing to the 
server side, where I'll still have to deal with performance problems (a 
different sort though at that point).

Any thoughts/input?  Thanks in advance.

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

Reply via email to