Optimizing row manipulations
Optimizing row manipulations
First, datatables is awesome.
Now that's out of the way, i've used datatable extensively to create a fantasy sports draft app. It works by manipulating rows from different tables (all using datatable), removing and adding rows. There are a total of 6 datatables on the page, 2 of which contain about 500 rows. See it here:
http://fantasysportstools.net/drafttool
Click on the + sign next to the players to see the row manipulations (i'm emulating a draft). Basically when a row is removed from the first table, a corresponding table needs to be searched for an entry to be removed, and also a row is added to the draft history table above. For the past 2 days i've been trying to optimize the common case, which is the draft button (+). I've disabled sort classes already, i've also played with not redrawing the database when doing updates for tables that aren't shown. Before i post code (it's long because there's a lot of manipulation of tables), i just wanted to see if there is any other optimization tricks i can play. The main performance hit comes from fnDeleteRow for the tables with 500 rows. It doesn't seem like a lot, so i'm not sure why it's taking so long. I'm also not sure if i can use serverside because of the extensive manipulation of rows (i'm also not too sure how server side works either). Any suggestions?
Now that's out of the way, i've used datatable extensively to create a fantasy sports draft app. It works by manipulating rows from different tables (all using datatable), removing and adding rows. There are a total of 6 datatables on the page, 2 of which contain about 500 rows. See it here:
http://fantasysportstools.net/drafttool
Click on the + sign next to the players to see the row manipulations (i'm emulating a draft). Basically when a row is removed from the first table, a corresponding table needs to be searched for an entry to be removed, and also a row is added to the draft history table above. For the past 2 days i've been trying to optimize the common case, which is the draft button (+). I've disabled sort classes already, i've also played with not redrawing the database when doing updates for tables that aren't shown. Before i post code (it's long because there's a lot of manipulation of tables), i just wanted to see if there is any other optimization tricks i can play. The main performance hit comes from fnDeleteRow for the tables with 500 rows. It doesn't seem like a lot, so i'm not sure why it's taking so long. I'm also not sure if i can use serverside because of the extensive manipulation of rows (i'm also not too sure how server side works either). Any suggestions?
This discussion has been closed.
Replies
A nice site you've developed there - very cool.
I have a look at the site with the profilers in Firebug and Webkit, and they show that there probably is come optimisation that can be done. It would be worth having a look at some profiles if you haven't already, as they show that the DataTables functions appear to be completing fairly quickly (although there is no doubt some optimisation that can be done - rebuilding the search array for each is likely to be slowing IE down a fair bit). A lot of the time seems to be going in the expansion_embedded.js library, also update_my_stats() and update_my_rank().
I'd recommend using the unminfied libraries (DataTables and any other JS source you include) to make the profiling easier to follow - so you get function names etc. And that way it can be looked at closer where the improvements can be made.
Allan
I am profiling when the + icon is clicked next to the players. It does show that most of the time it's executing fnDeleteRow, but it's only when the table needs to be redrawn. I called it with the redraw parameters set to false and the performance for most of the time is reasonable. So it's probably something with the redrawing of tables. THe profiler also confirmed my suspicion, as fnScrollDraw eats up a lot of time. The profiler also shows curCSS being called only 23 times but eats up a lot of time. I tried googling but am not sure what that function does.
I've started digging into javascript this month, so i'm a little slow. Do you have suggestions as to where i can look into?
thanks!
Yup I was profiling the moving of the rows. The thing that I've noticed is that fnDeleteRow itself doesn't take much time, but something inside it is, I suspect that it is _fnBuildSearchArray, but it's difficult to say without the non-min version being used: http://datatables.net/dev/3050.png . I'm wondering if that can be optimised a bit by just doing a splice (I need to check out how the array indexes are done - I'll get back to you on that), but for now, I'd suggest trying an experiment - comment out the call to _fnBuildSearchArray in fnUpdate in the non-min version and see if that improves your render time.
Allan
I've been using the non min version offline to try it out, but i updated the online version too, so hopefully that can help you. Please keep me updated to see if just doing a splice would be better.
thanks so much for your help!
Good to hear that worked. I've just done some work on DataTables to improve the speed of fnDeleteRow, fnAddData and fnUpdate (fnDeleteRow will probably see the biggest benefit at the moment). This will hopefully make your table draw significantly faster when using these API functions. You can grab the development version from the download page ( http://datatables.net/download/ - get the 'nightly' DataTables version).
It's also given me a number of ideas for how to speed the filtering up in future. That will require a bit more of an extensive overhaul of how filtering works in DataTables, and I'll need a bit of time to work on that, but I'd say it's a promising avenue when considering the API functions, and possibly a few other points such as sorting.
Edit - sorry I missed your question about what the function does. Basically it creates a cached array from the table data to speed up filtering (and make the smart filtering possible). This is fine, but rebuilding the entire array was not needed, simply deleting the row which is in question is all that was required. And this is the change that I've put in place.
Regards,
Allan
Allan