5

I have a table that gets populated with a list of connected users. The list itself doesn't change very often, but one of the things on each row is a timer(hh:mm:ss) that updates each second. To update the timers, I'm doing something like this:

var curTime = new Date().getTime() / 1000;
$('.timerCell').each(function(){
    var $this = $(this);
    var initialTime = $this.data('sessionStartTimestamp'); // .data gets when the cell is dynamically created based on data received in an ajax request.
    $this.text(unixToHumanTime(curTime - initialTime));
});

The issue I'm having with this is: each time that a single timer cell is updated, it triggers a redraw. Is there a way to tell the browser to wait to redraw? or perhaps some way to group these updates into a single update. I had also thought of re-rendering the entire tbody each time an update happens, but thought that would probably be more system intensive than just updating the cells.

Eric Seastrand
  • 2,473
  • 1
  • 29
  • 36
  • so you're saying that every second all of the timers trigger a redraw – Greg Guida Dec 21 '11 at 20:43
  • I had thought that the scroll lag I was running into was caused by all these redraws, but as it turns out, it was coming from having animated box shadows on the cells (to make them glow a different color based on the time in them) It would still be a performance benefit to avoid all these redraws, but it's not really that important anymore since it's not the real issue. – Eric Seastrand Dec 21 '11 at 21:50

2 Answers2

4

Don't use jQuery for this. Let's manually make a document fragment and append it to the DOM so we don't cause a re-draw.

var curTime = new Date().getTime() / 1000;
$('.timerCell').text(function(){
    var elm = $(this).get(0);
    var frag = document.createDocumentFragment();

    elem.removeChild(elem.childNodes[0]);
    frag.appendChild(document.createTextNode(unixToHumanTime(curTime - initialTime)));
    elem.appendChild(frag);
});
Greg Guida
  • 7,302
  • 4
  • 30
  • 40
  • by creating a document fragment we only cause the fragment to be redrawn each time rather than the entire document. But like he explains in the comments his issue was caused by box-shadows not excessive re-flows – Greg Guida Dec 27 '11 at 18:55
2

Try this:

var curTime = new Date().getTime() / 1000;
$('.timerCell').text(function(){
    var initialTime = $(this).data('sessionStartTimestamp'); 
    return unixToHumanTime(curTime - initialTime);
});

Many jQuery methods allow you to pass a callback function with a return value. Strictly speaking, this code is still updating .timerCells one at a time, but it's doing so more efficiently.

Blazemonger
  • 90,923
  • 26
  • 142
  • 180