Prevent Long Running JavaScript from Locking Up Browser

Prevent long running javascript from locking up browser

if you can turn your calculation algorithm into something which can be called iteratively, you could release control back the browser at frequent intervals by using setTimeout with a short timeout value.

For example, something like this...

function doCalculation()
{
//do your thing for a short time

//figure out how complete you are
var percent_complete=....

return percent_complete;
}

function pump()
{
var percent_complete=doCalculation();

//maybe update a progress meter here!

//carry on pumping?
if (percent_complete<100)
{
setTimeout(pump, 50);
}
}

//start the calculation
pump();

How to avoid freezing the browser when doing long-running computations in Javascript

If you only need to do a calculation and don't need to access the DOM during the long running calculation, then you have two options:

  1. You can break the calculation up into pieces and do a piece at a time on a setTimeout(). On each setTimeout() call, the browser will be free to serve other events and will keep the page alive and responive. When you finish the last piece of the calculation, you can then carry out the result.
  2. You can run the calculation in the background using a webworker in modern browsers. When the calcuation is done in the webworker, it sends a message back to the main thread and you can then update the DOM with the result.

Here's a related answer that also shows an example: Best way to iterate over an array without blocking the UI

How to prevent IE from freezing while long running script execution?

Since version 10 IE supports web-workers which allow running JS on a different thread than the main thread.

How to stop intense Javascript loop from freezing the browser

I would ditch the "each" function in favour of a for loop since it is faster. I would also add some waits using the "setTimeout" but only every so often and only if needed. You don't want to wait for 5ms each time because then processing 3500 records would take approx 17.5 seconds.

Below is an example using a for loop that processes 100 records (you can tweak that) at 5 ms intervals which gives a 175 ms overhead.

var xmlElements = $(xmlDoc).find('Object');
var length = xmlElements.length;
var index = 0;
var process = function() {
for (; index < length; index++) {
var toProcess = xmlElements[index];
// Perform xml processing
if (index + 1 < length && index % 100 == 0) {
setTimeout(process, 5);
}
}
};
process();

I would also benchmark the different parts of the xml processing to see if there is a bottleneck somewhere that may be fixed. You can benchmark in firefox using firebug's profiler and by writing out to the console like this:

// start benchmark
var t = new Date();
// some xml processing
console.log("Time to process: " + new Date() - t + "ms");

Hope this helps.

How to prevent long running service cause browser to popup Kill / Wait alert?

i suggest you to set the fifth param of the oModel.create method to 'true' which will cause the call to be asynchronous (and remove the setTimeOut()).

oModel.create('/serviceURL?sap-client='
+ sapClient, requestObj, null, function(
data, oev) {

// Success function
console.log('fffff');

that.getView().setBusy(false);
if (data.JsonOut.indexOf("message:") != -1) {
var arr = data.JsonOut.split("message:");

sap.m.MessageBox
.alert(arr[1].split(",")[0]);
}

that.onBindTable();
}, function(err) {
// Error function
that.getView().setBusy(false);
var errorObj = JSON.parse(err.response.body);

var sMsgs = errorObj.error.message.value;
sap.m.MessageBox.alert(sMsgs);

}, true);

Find a hint there, not sure if it's revelent as i couldn't find the javascript API reference.

https://archive.sap.com/discussions/thread/3503659

Javascript - how to avoid blocking the browser while doing heavy work?

You could nest your calls inside a setTimeout call:

for(...) {
setTimeout(function(i) {
return function() { doSomethingHeavy(i); }
}(i), 0);
}

This queues up calls to doSomethingHeavy for immediate execution, but other JavaScript operations can be wedged in between them.

A better solution is to actually have the browser spawn a new non-blocking process via Web Workers, but that's HTML5-specific.

EDIT:

Using setTimeout(fn, 0) actually takes much longer than zero milliseconds -- Firefox, for example, enforces a minimum 4-millisecond wait time. A better approach might be to use setZeroTimeout, which prefers postMessage for instantaneous, interrupt-able function invocation, but use setTimeout as a fallback for older browsers.

How to process the big loop without freezing the browser using setTimeOut function in javascript?

You can use a loop variable, like the following code. In this example, the function increases every element by 1. The timeout period is 1 millisecond.

    var currentIndex;
function processNthElement(array) {
if (currentIndex >= array.length)
{
//the whole array has been processed, do what you need to do
//with the results here
return;
}

//do what you want with the array element here
array[currentIndex]++;

currentIndex++;

setTimeout(function () {
processNthElement(array);
}, 1);
}
function processArrayWithSetTimeout(array) {
currentIndex = 0;
processNthElement(array);
}

Then to process a large array, just call processArrayWithSetTimeout(array). However since we are using timeout, you need to process the result at the very last function call(see the comment in the function). If an array has 10000 elements, it will take more than 10000 milliseconds or 10 seconds to process, but the UI won't be freezed.

Note that this still processes the array sequentially but without freezing the UI as it waits for a while after processing 1 element.



Related Topics



Leave a reply



Submit