Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple DOM updates in a single redraw/reflow?

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.

like image 241
Eric Seastrand Avatar asked Dec 21 '11 20:12

Eric Seastrand


2 Answers

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);
});
like image 194
Greg Guida Avatar answered Sep 20 '22 23:09

Greg Guida


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.

like image 21
Blazemonger Avatar answered Sep 23 '22 23:09

Blazemonger