Let's say I have this javascript function:
function pauseComp(ms) {
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < ms);
}
and a css3 animation (for instance, <i class="icon-spinner icon-spin"></i> from the new font-awesome 3). When I run the javascript function above, it stops the spinner while the function is running. See what I'm talking about here. Basically, javascript stops css animations, and I'm wondering why, or if anyone else has noticed this/found a workaround. I've tried putting it in a setTimeout(fn,0), where fn is the long process, but then realized why that will also not work (js is not multithreaded). Anyone seen this happening?
Update: Interestingly, it looks like this isn't as much of a problem in Safari, although interaction with the browser interface is still being affected.
A browser page is single threaded. Updating the UI happens on the same thread as your javascript program. Which also means that any animation will not draw new frames while Javascript code is being executed. Typically, this is no big deal because most JS code is executed very quickly, faster than a single animation frame.
So the best advice is simply this: Don't do that. Don't lock up the JS engine for that long. Figure out a cleaner way to do it.
However, if you must, there is a way. You can get an additional thread via HTML5's Web Workers API. This isn't supported in older browsers, but it will allow you to run some long running CPU sucking code away from the main webpage and in it's own thread, and then have it post back some result to your page when it's done.
Related
var len1 = $("div").length
// can a new div inserted here?
var len2 = $("div").length
console.log(len1 === len2) // always true?
Is it possible for some rogue script to insert a new div between jQuery calls?
Short answer: No.
Longer answer: You don't seem to be using alert or confirm in your code, and so the couple of weird edge cases in Firefox (which may only be in older versions) related to alert and confirm don't come into play. This answer from 2010 goes into those in detail.
But no, barring the above, no JavaScript code that accesses the DOM can be run between one statement and another in your code. Browsers run JavaScript with a single UI thread (and zero or more web worker threads, but web worker threads can't access the DOM).
Is there any possibility of analyzing performance of javascript on mobile. Like I have a situation where say a list is rendered quite slowly on mobile (like 3-4 minutes).
Initially i thought its because of the data model and kind of query i am using is causing the delay, but when i took database traces all the query execution is really fast.
I also got hold of n/w trace of attached device (which is simulator in my case) and could see all the data being buffered in under 3 secs. So the only culprit what i anticipate is the JS running behind to render all the data. But i dont know how to trace or do performance analysis of JS on mobile. Any idea??
I'm not sure if this is what you're looking for, (your question somewhat confuses me) but here's how to test how long a piece of code takes in JavaScript:
var start = new Date().getTime(); //milliseconds
// your section of code
// ...
var elapsed = new Date().getTime() - start;
You could do that to test specific sections of your code for execution length.
If you had <div id="timetaken"></div> somewhere in your HTML, you could add
document.getElementById('timetaken').innerHTML="Time taken: " + elapsed;
And then when your code completes it would display how long that bit of code took to complete in your HTML so that you can see it on a mobile device.
I am working on a mobile web app that is primarily self-contained and communicated with the server only when necessary. Currently, the libraries being used are:
jQuery 1.6.4
jQuery UI 1.8.3
Modified/patched version of jQTouch
Up until the release of iOS 5 we were also using touchscroll.js but it is no longer needed since Safari now supports position: fixed and native scrolling.
Since the release of iOS 5, seemingly at random, this exception is raised:
JavaScript: Error undefined JavaScript execution exceeded timeout
Once it is raised, no JS code that runs for more than a very short period of time (say 1ms) will be executed by Safari. Refreshing the page, going to a new page, or going to a new domain has no effect. Any and all JS code, even something as simple as
for(var i = 0; i < 30; i++) ;
will not be executed by the browser without the exception being raised. The only way around this is to force kill Safari and restart it. I suppose it is also possible to wrap any remotely "heavy duty" code in the application in a window.setTimeout(..., 1) or take advantage of Web Workers for everything but UI updates but that doesn't seem like a very good solution as the application is fairly large and it would require a substantial rewrite.
Has anyone encountered this issue before? How would you go about debugging something like this as it isn't any single piece of code that seems to put Safari into this broken state and it can happen seemingly at random?
I tried to figure out what the timeout of the JS engine is in mobile Safari by doing the following:
var start, end;
start = new Date();
try {
while(true);
} catch (ex) {
alert('test');
}
end = new Date();
console.log(Number(end) - Number(start) + 'ms');
Unfortunately it seems this timeout exception isn't a JS exception so it cannot be caught in a try/catch block; however, it appears the max timeout period is in the realm of several seconds. None of the code in our app locks the browser/JS engine for that long (as it would provide a terrible UX) and most if not all of it probably has a sub 300ms execution time (including anything that's "heavy duty").
Are you using watchPosition? see this answer if so: JavaScript execution exceeded timeout
I've been ripping my hair out over this issue ever since iOS 5 was released - I feel your pain!
I have recently started to tinker with Project Euler problems and I try to solve them in Javascript. Doing this I tend to produce many endless loops, and now I'm wondering if there is any better way to terminate the script than killing the tab in Firefox or Chrome?
Also, is firebug still considered the "best" debugger (myself I can't see much difference between firebug and web dev tool in safari/chrome ).
Any how have a nice Sunday!
Firebug is still my personal tool of choice.
As for a way of killing your endless loops. Some browsers will prevent this from happening altogether. However, I still prefer just going ctrl + w, but this still closes the tab.
Some of the other alternatives you can look into:
Opera : Dragonfly
Safari / Chrome : Web Inspector
Although, Opera has a nice set of developer tools which I have found pretty useful. (Tools->Advanced->Developer Tools)
If you don't want to put in code to explicitly exit, try using a conditional breakpoint. If you open Firebug's script console and right-click in the gutter next to the code, it will insert a breakpoint and offer you an option to trigger the breakpoint meets some condition. For example, if your code were this:
var intMaxIterations = 10000;
var go = function() {
while(intMaxInterations > 0) {
/*DO SOMETHING*/
intMaxIterations--;
}
};
... you could either wait for all 10,000 iterations of the loop to finish, or you could put a conditional breakpoint somewhere inside the loop and specify the condition intMaxIterations < 9000. This will allow the code inside the loop to run 1000 times (well, actually 1001 times). At that point, if you wish, you can refresh the page.
But once the script goes into an endless loop (either by mistake or design), there's not a lot you can do that I know of to stop it from continuing if you haven't prepared for this. That's usually why when I'm doing anything heavily recursive, I'll place a limit to the number of times a specific block of code can be run. There are lots of ways to do this. If you consider the behaviour to be an actual error, consider throwing it. E.g.
var intMaxIterations = 10000;
var go = function() {
while(true) {
/*DO SOMETHING*/
intMaxIterations--;
if (intMaxIterations < 0) {
throw "Too many iterations. Halting";
}
}
};
Edit:
It just occurred to me that because you are the only person using this script, web workers are the ideal solution.
The basic problem you're seeing is that when JS goes into an endless loop, it blocks the browser, leaving it unresponsive to any events that you would normally use to stop the execution. Web workers are still just as fast, but they leave your browser unburdened and events fire normally. The idea is that you pass off your high-demand tasks (in this case, your Euler problem algorithm) to a web worker JS file, which executes in its own thread and consumes CPU resources only when they are not needed by the main browser. The net result is that your CPU still spikes like it does now, but your browser stays fast and responsive.
It is a bit of a pest setting up a web worker the first time, but in this case you only have to do it once. If your algorithm never returns, just hit a button and kill the worker thread. See Using Web Workers on MDC for more info.
While having Firebug or the webkit debuggers is nice, a browser otherwise seems like overhead for Project Euler stuff. Why not use a runtime like Rhino or V8?
I am creating a really big JavaScript object on page load. I am getting no error on firefox but on Internet Explorer I am getting an error saying:
Stop running this script ?
A script on this page is causing your web browser to run slowly. If it continues to run, your computer might become unresponsive.
Is there any size limit for Javascript objects in Internet Explorer ? Any other solutions but not dividing the object?
The key to the message your receiving is the "run slowly" part, which relates to time. So, your issue is not object size, but the time taken to construct the object.
To refine things even further, the issue is not the time taken to construct the object either. Rather, IE counts the number of javascript statements it executes, resetting this count when it executes an event handler or a setTimeout function.
So, you can prevent this problem by splitting your code into multiple pieces that run inside calls to setTimeout(...);
Here's an example that may push you in the right direction:
var finish = function(data) {
// Do something with the data after it's been created
};
var data = [];
var index = 0;
var loop;
loop = function() {
if (++index < 1000000) {
data[index] = index;
setTimeout(loop, 0);
} else {
setTimeout(function(){ finish(data); }, 0);
}
}
setTimeout(loop, 0);
The resources available to JavaScript are limited by the resources on the client computer.
It seems that your script is using too much processing time while creating that object, and the 'stop script' mechanism is kicking in to save your browser from hanging.
The reason why this happens on Internet Explorer and not on Firefox is probably because the JavaScript engine in Firefox is more efficient, so it does not exceed the threshold for the 'stop script' to get triggered.
that is not because of the size but because of the big quantity of loops you are executing and the big execution time. if you cut it into smaller parts it should work ok.
Try lowering the complexity of functions your running. Can you post it so that we can look at the loops and try to help?
Edit:
I supose you want to do all that on the client side for some reason. The code seems to need to much execution to be runing on the client side.
Can't you do the calculations on the server side? If this is all to initialize the object, you can cache it to avoid reprocessing and just send a generated json to the javascript side.
It does seem cachable
You must be using big loops or some recursive logic in the code. It really doesn't depend on the size of the object—it depends on the CPU resources it uses (memory, processor, etc.).