Thursday, January 22, 2009

The past day or two I've been using selectors like this to manipulate tabular data:

$("table#summary tr:nth-child("+k+")")

I was using the selectors to pump a table of audit data into a summary table, and the whole process was 5-6 seconds for under 50 rows. There were lots of ":contains" statements in there, so naturally I attacked those first, caching the results in .data() fields. Yet most of the lag time remained.
So I cranked on the Firebug profiler and profiled the function that does the heavy lifting. Calls to nth-child were taking up 4700ms out of about 5000ms total!
After staring at it for a minute, I recalled that :nth-child looks for all elements that are the nth child of their parent -- that's what I want, right? -- but it does not assume that they are direct descendants of the preceding element in the selection chain.

"Matches all elements that are the nth-child of their parent ... While :eq(index) matches only a single element, this matches more than one ..."

This is certainly what you need in some cases, but if your jquery consists of a set of siblings and you just want to grab a particular element by index, it's far quicker to do one of the following:

$("table#summary tr:eq("+k+")")

$("table#summary tr").eq(k)

Once I made that change, Firebug's Profiler timing went from 5000ms+ down to the 300-400ms range. Lesson learned.