fnUpdate() lags browser when used constantly

fnUpdate() lags browser when used constantly

doncullendoncullen Posts: 32Questions: 2Answers: 0
edited October 2010 in Bug reports
Running profiler via firebug shows time for fnUpdate() as 800 ms, emphasis seems to be on _fnReDraw, then on _fnSort.

My script basically loads 6 rows, does a considerable amount of manipulation on those rows, then repeats the process every 5 seconds. So it's quite browser intensive. I've been working on optimizing my script.

Initially, my processThis function was what was eating the browser alive (due to frequent addClass/removeClass usage), but I've managed to recode that function so it's only eating up 148 ms while in function (0.41 ms avg).

The profiler shows the current top seven hogs to be:

1. onreadystatechange() at 85 ms average, time spent in function at 855 ms <--- jquery
2. httpData() at 427 ms average, time spent in function at 855 ms <--- jquery
3. globalEval() at 427 ms average, time spent in function at 855 <--- jquery
4. fnUpdate() at 12 ms average, time spent in function at 800 ms <--- datatables
5. _fnReDraw at 11 ms average, time spent in function at 742 ms <--- datatables
6. _fnSort at 11 ms avg, time spent in function at 742 ms <--- datatables
7. processActiveQueue at 367 ms avg, time spent in function at 735 ms <--- my javascript

I will be working on the top three myself since that isn't related to datatables (but if you have feedback on those, it's always welcome). I will also be working on optimizing processActiveQueue. But #4 to #6 concern me. Hence my posting here.

My reasoning is: I modify the rows by adding, updating, removing rows every five seconds. My concern here is that the table is re-sorting, re-drawing every row change. This quickly adds up for the intensiveness of it. An idea I've had is when it starts it's usual run of updating the table, I could disable sorting and drawing until it's finished processing the data, then execute sorting/drawing at the end of the function. This should help shave down the intensiveness of it considerably.

So my question for you guys is: how would one go about disabling re-draw, and sorting at the start of a function, then re-enable (as well as execute) sorting and redraw at the end of that same function? I checked Examples, API, and Development, as well as searched the forums and was not able to find an answer. So any feedback will be appreciated.

While I'm waiting for one of you to respond, I will go ahead and work on the other data hogs. Thanks in advance for your time and assistance.

Replies

  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    First thing I'd recommend is trying out the nightly build of DataTables ( http://datatables.net/download ) which has a small improvement which might help your fnUpdate call. How many rows of data are you dealing with?

    You can disable the redraw and the rebuilding of the internal structures using the API call for fnUpdate http://datatables.net/api#fnUpdate - if you aren't using scrolling in DataTables then the last parameter for the internal structures is certainly a good option. If you are batch updating, then you can disable the draw as well and then just call fnDraw to redraw in one go.

    Regards,
    Allan
  • doncullendoncullen Posts: 32Questions: 2Answers: 0
    edited October 2010
    Replacing it with nightly build seems to have improved performance some. The processActiveQueue is now at #3 for top data hog, while fnUpdate() has dropped to #5. I'm still seeing the lockup, but when I examine the metrics in Firebug, I can see the processActiveQueue function is the worst offender. So I'll be concentrating on optimizing that function. That function does have some references to the datatables plugin, but I'm trying to determine whether it's the datatables or if it's something else.

    I'm doing batch updating, so I disabled draw and sorting for the fnUpdate commands that I had, and set it to enable on the last update command. That improved performance a bit.

    Edit: After applying the above change and below changes, fnUpdate has dropped way down in the list, so now fnReDraw is now at #5, while fnSort is at #6. Screen shot is below of the firebug output.

    I also found out that I was executing auto-resizing everytime the queue update function ran. I modified the code so it'd execute auto-resize every 15 seconds independently of the queue check.

    I then increased the rows from the usual six rows to 40 rows to test out the performance.

    The changes cut down the lockup from 3 seconds to one second. That's in Chrome. With Firefox, the lockup has stopped completely killing the browser, it now simply locks up for about three seconds.

    Check out the firebug output:
    http://dl.dropbox.com/u/109745/untitled.PNG
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    That is sounding promising - nice one. Although your screenshot still shows _fnReDraw being called 81 times. Was that during a simple update? I guess ideally you want to call it only once when all rows have been updated (assuming I am understanding the set up correctly).

    Allan
  • doncullendoncullen Posts: 32Questions: 2Answers: 0
    I let the function run twice, there were about 40 rows, so I'm assuming it counted both row update runs?

    Here's link to the code.
    http://dl.dropbox.com/u/109745/queueManagement.js

    I'm still working on optimizing it so it doesn't lock up the browser, but as usual, I'm open to ideas.
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    That's for the code - that's quite helpful. There are two parts of the code where I think there could be a bit of a performance tweak. Both very similar - where you call fnUpdate or fnAddData. For example:

    [code]
    if(SessionIDFound){
    // Update row
    oTable.fnUpdate(customer[j].QueuedTime, i, 4);
    } else {
    // New session

    $('#thependingqueue').dataTable().fnAddData([
    customer[j].SessionID,
    customer[j].Device,
    customer[j].Source + customer[j].ANI,
    customer[j].Region,
    customer[j].QueuedTime,
    customer[j].FullSkillSet,
    customer[j].Desc
    ]);
    oTable.fnAdjustColumnSizing();
    }
    [/code]
    Firstly, you'll want to add the do not redraw option to these functions, and also the fnAddData in the other similar block.

    Then note that you are actually doing a redraw for each time around the loop which contains these blocks - which is why it is showing up 80 odd times. Do the redraw and column sizing outside of the loop (so all fnUpdate and fnAddData calls do not redraw the table). Hopefully you'll see a significant increase in speed.

    Allan
  • doncullendoncullen Posts: 32Questions: 2Answers: 0
    I modified the code to completely disable drawing, and added code to the end of the function to run redraw. So it'd only have to redraw once. Did that for both blocks. Still seeing the lockup, and draw seems to still be called often.

    Firebug results:
    http://dl.dropbox.com/u/109745/untitled2.PNG

    Updated code:
    http://dl.dropbox.com/u/109745/queueManagement.js
This discussion has been closed.