Skip to content Skip to sidebar Skip to footer

Dom Update Followed By A Big Loop Doesn't Render In Time

A piece of my page has ~9000 elements in it and it has to be rebuilt often, which can take a few seconds. So, I made a little overlay widget that covers the element with a Loading.

Solution 1:

functiondo_rebuild() {
  for (var i=0;i<9000;i++) {
    // append element...
  }
  hideOverlay();
}


functionrebuild() {
  showOverlay();    // The overlay will appearwindow.setTimeout('do_rebuild();',1);
}

Is the only cross-browser way I know of.

Solution 2:

You need to put your loop inside a set timeout so that it doesn't hold up the page. Even if your overlay is displayed, nobody likes their page freezing

var counter = 0;
functionrebuild() {
    showOverlay();
    doWork();
}
functiondoWork() {
    if(counter < 9000){
        // append element
        counter++;
        setTimeout(function(){
            doWork();
        },10);
    }
    else {
        hideOverlay();
    }
}

EDIT: This answer will actually take significantly longer to process the page though. Somewhere in the realm of 90 seconds which is pretty unacceptable, the other alternative could be to set a timeout every 100 iterations, which will add about 1 sec to the total load time, but should stop the page from freezing.

function doWork() {
    if(counter < 9000){
        // append elementif(counter % 100 == 0) {
            setTimeout(function(){
                doWork();
            },10);
            counter++;
        }
        else {
            doWork();
            counter++;
        }
    }
    else {
        hideOverlay();
    }
}

Solution 3:

The other answers show how to do this in a "pseudo-threading" way, using timers.

In the meantime I have learned about Web Workers, which are a threading solution that separates script execution from DOM updates.

They are currently supported in WebKit and Firefox, and support is planned for IE 10.

Solution 4:

you could try this:

var loopCount = 0,
    build = function() {

    var frgm = document.createDocumentFragment();
    for (var i = 0; i < 200 && loopCount < 9000; i++) {
        // some codes
        frgm.appendChild(someElement);
        loopCount ++;
    }
    parentNode.appendChild(frgm);

    if (loopCount < 9000) {
         setTimeout(build, 10);
    }
};

functionrebuild() {
  showOverlay();    // The overlay never appears...build();
  hideOverlay();
}

Post a Comment for "Dom Update Followed By A Big Loop Doesn't Render In Time"