1

I do (in JavaScript/jQuery) heavy computations. The problem is that these computations are blocking the UI thread and I (tried and) can't find a way to avoid this.

Some requirements:

  • I can't use webWorkers
  • The computations must be on client side (I can't make an AJAX call for doing them on server side)

I'm an Android programmer to so I know how to do that in Java (launching thread, make computations, send data to UI Thread) and so I'm trying to do the same thing here.

So these heavy computations can have only one active instance (I will make a GIF for advise the user he can't launch this again before that end) so don't need to manage multiple call (end last, start new).

Here is the code:

var datas = []; // 10000 datas here
function sortBy(param, paramType, order) {
    var newArray = JSON.parse(JSON.stringify(datas));

    window.setTimeout(function(){
        var end = false;
        for (var i = newArray.length - 1; i > 0 && !end; i--) {
            end = true;
            for (var j = 0; j < i - 1; j++) {
                var sort = false;

                if (paramType.localeCompare("str") == 0) {
                    if (newArray[j + 1][param].localeCompare(newArray[j][param]) < 0 && order.localeCompare("up") == 0) {
                        sort = true;
                    } else if (newArray[j + 1][param] > newArray[j][param] && order.localeCompare("down") == 0) {
                        sort = true;
                    }
                } else if (paramType.localeCompare("nbr") == 0) {
                    if ((newArray[j + 1][param] - newArray[j][param]) < 0 && order.localeCompare("up") == 0) {
                        sort = true;
                    } else if ((newArray[j + 1][param] - newArray[j][param]) > 0 && order.localeCompare("down") == 0) {
                        sort = true;
                    }
                }

                if (sort) {
                    var tmp = newArray[j + 1];
                    newArray[j + 1] = newArray[j];
                    newArray[j] = tmp;
                    end = false;
                }
            }
        }

        datas = newArray;
    }, 0);
}

I'm sorting datas (and for avoid data reload from server for mobiles, it's why I can't make this on server side).

I tried to copy (full copy, no reference) the array in the function, because I thought that the initial variable who contains the data, because she don't are in a function, was on the UI thread, and accessing it into the function makes call to UI thread. => doesn't work. (and so I'm wrong).

I tried to launch the computations in a setTimout( {computations}, 0) as you can see, that was a solution that I see a lot of time on other Stack Overflow similar questions => doesn't work too.

I run in a basic JavaScript environnement, the only library I use is jQuery.

So, is here a way to force this computations to work in an other thread (or something like that), or more global, don't block UI thread?

3
  • 1
    Have a look here, where the suggestion is to break the background work into chunks, with breaks in between for the UI to update. Commented May 3, 2016 at 16:11
  • Why can't you use Web Workers, exactly? Commented May 3, 2016 at 18:05
  • @AkshatMahajan, because don't have compatibility with all devices/browser. Commented May 4, 2016 at 7:24

1 Answer 1

4

Javascript is single threaded. Unless you use a wb worker, your only choice is to split the computation up into pieces. Execute a piece of the calculation, then use setImmediate or setTimeout to schedule the next piece to run. This will give the UI time to execute and prevent the blocking you found.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.