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

Reply via email to