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?
Related
I've set up a simple testbed for WatiN (ver 2.1) which reads:
var browser = new IE();
browser.GoTo("http://www.google.co.il"); // webpage doesn't matter really
browser.RunScript("alert(123)");
This works only if KB3025390 is not installed. Installing it breaks the above test with an UnAuthorizedAccessException which has HRESULT set to E_ACCESSDENIED. What gives? Is there any workaround?
Update: Using IWebBrowser2.Navigate2 along with "javascript:console.log(123)" type of scripts works however
it makes me feel uneasy using such a backchannel
the scripts run through this back-channel of .Navigate2() may only have a max length of about 2070 chars (give or take) otherwise they get forcibly truncated to this length leading to javascript errors upon attempting to run them
using .Navigate2(), even with the most trivial script, will clog the ready state of Internet Explorer for good in the sense that it will be set to READYSTATE_LOADING without any hope of getting rid of it. In simple terms this means that once you use this hack, you either have to perform every single subsequent operation in WatiN in a "dont-wait-for-webpage-to-load" fashion (GoToNoWait, ClickNoWait etc) lest your code freezes upon waiting for the browser to turn back to READYSTATE_COMPLETE (which will never come about ofcourse as already mentioned).
there appears to be a much broader issue here in the sense that I can't even access the properties of an IHtmlWindow2 object p.e. window.document throws an unauthorized exception again making it virtually impossible to transfer over to the C# world the return-values of the scripts I'm running (using Expando etc) for documents other than window.top.document (for the window.top.document window there is IWebBrowser2.Document which does the trick)
Update#2: The folks over at the selenium project have also noticed this issue:
https://code.google.com/p/selenium/issues/detail?id=8302
A bug report has been created as well:
https://connect.microsoft.com/IE/feedback/details/1062093/installation-of-kb3025390-breaks-out-of-process-javascript-execution-in-ie11
Update#3: IHTMLWindow2.setInterval and IHTMLWindow2.setTimeout also throw UnauthorizedAccess exceptions. These methods are not marked as deprecated in:
http://msdn.microsoft.com/ko-kr/library/windows/desktop/aa741505%28v=vs.85%29.aspx
yet they have wounded up suffering from the same cutbacks all the same.
Update#4: I gave the approach recommended in this post a shot:
https://stackoverflow.com/a/18546866/863651
In order to dynamically invoke the "eval" method of the IHTMLWindow2 object (or any other method really). Got the same "System.UnauthorizedAccessException" as above. So no joy here either.
Microsoft recommends using "eval" over "execscript" however after the above experiment I suspect that they are refering to accessing "eval" only from within the browser.
As far as I can tell thus far, when it comes to the full-fledged IE11+ using "eval" out-of-process (via COM) appears to have been completely prohibited along with any other function-invocation of the window object, the only exception being the back-channel of the .Navigate2() mentioned above.
It turns out Microsoft eventually backpedaled on its decision to kill off .execScript at COM-level. Just install the latest updates for Windows including kb3025390: One of the updates for IE that came after kb3025390 brings back .execScript functionality at COM-level
Note, however, that .execScript is not accessible through IE's javascript anymore. In that context it's gone for good.
fyi: this one is also not working
ieInstance.Document.Script.<methodNameString>(<commaSeperatedParameterString>)
try this worked for me at some places but not all places
ieObject.Navigate "javascript:<methodNameString>(<commaSeperatedParameterString>)", Null, "_parent"
or
ieObject.Navigate2 "javascript:"<methodNameString>(<commaSeperatedParameterString>)", Null, "_parent"
now trying to find out solution using eval
I have found a way around the problem of an update installing automatically. You can just create a simple batch file with following content.
{code}
#echo off
wusa /uninstall /kb:3025390/quiet /norestart
END
{code}
Then go to task scheduler, create a new task for this batch file to run every one hour or day as per your requirements. Add it as a system task so it runs in the background and does not affect the running automations.
While profiling my webapp I noticed that my server is lighting fast and Chrome seems to be the bottleneck. I fired up Chrome's "timeline" developer tool and got the following numbers:
Total time: 523ms
Scripting: 369ms (70%)
I also ran a few console.log(performance.now()) from the main Javascript file and the load time is actually closer to 700ms. This is pretty shocking for what I am rendering (an empty table and 2 buttons).
I continued my investigation by drilling into "Scripting":
Evaluating jQuery-min.js: 33ms
Evaluating jQuery-UI-min.js: 50ms
Evaluating raphael-min.js: 29ms
Evaluating content.js: 41ms
Evaluating jQuery.js: 12ms
Evaluating content.js: 19ms
GC Event: 63 ms
(I didn't list the smaller scripts but they accounted for the remaining time) I don't know what to make of this.
Are these numbers normal?
Where do I go from here? Are there other tools I should be running?
How do I optimize Parse HTML events?
For all the cynicism this question received, I am amused to discover they were all wrong.
I found Chrome's profiler output hard to interpret so I turned to console.log(performance.now()). This led me to discover that the page was taking 1400 ms to load the Javascript files, before I even invoke a single line of code!
This didn't make much sense, so revisited Chrome's Javascript profiler tool. The default sorting order Heavy (Bottom Up) didn't reveal anything meaningful, so I switched over to Chart mode. This revealed that many browser plugins were being loaded, and they were taking much longer to run than I had anticipated. So I disabled all plugins and reloaded the page. Guess what? The load time went down to 147ms.
That's right: browser plugins were responsible for 90% of the load time!
So to conclude:
JQuery is substantially slower than native APIs, but this might be irrelevant in the grand scheme of things. This is why good programmers use profilers to find bottlenecks, as opposed to optimizing blindly. Don't trust people's subjective bias or a "gut feeling". Had I followed people's advise to optimize away JQuery it wouldn't have made a noticeable difference (I would have saved 100ms).
The timeline tool doesn't report the correct total time. Skip the pretty graphs and use the following tools...
Start simple. Use console.log(performance.now()) to verify basic assumptions.
Chrome's Javascript profiler
Chart will give you a chronological overview of the Javascript execution.
Tree (Top Down) will allow you to drill into methods, one level at a time.
Turn off all browser plugins, restart the browser, and try again. You'd be surprised how much overhead some plugins contribute!
I hope this helps others.
PS: There is a nice article at http://www.sitepoint.com/jquery-vs-raw-javascript-1-dom-forms/ which helps if you want to replace jQuery with the native APIs.
I think Parse HTML events happen every time you modify the inner HTML of an element, e.g.
$("#someiD").html(text);
A common style is to repeatedly append elements:
$.each(something, function() {
$("#someTable").append("<tr>...</tr>");
});
This will parse the HTML for each row that's added. You can optimize this with:
var tablebody = '';
$.each(something, function() {
tablebody += "<tr>...</tr>";
});
$("#someTable").html(tablebody);
Now it parses the entire thing at once, instead of repeatedly parsing it.
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'm not a JavaScript Wizard by a long shot. But I am a web-developer and so I need to know my way around it at least a bit.
Something I'll often do is simply alert a variable to see what it is.
However, the problem is that I'll often get a result like: "object HTMLInputElement". To me this means little to nothing. Sure I can look it up, but I need to alert children() of children() of children(), etc...
I've tried walking through the JavaScript with Firebug, but for some reason this is very slow. Firefox hangs when I start a debug session, for every single debug session and I don't know why.
So, I want to inform if there is a way to get detailed info on variables some other way. Or a system I can use to work with to make things easier.
I find the developer tools in Chrome work quite well, giving a good amount of detail on demand (usually just hovering the mouse over the variable in the script tab; if that variable is a structured object, a little tree control appears and you can drill down). But then, I don't have your Firebug issue either (or at least, not often anymore).
Debugging with alert is very time-wasteful and, as you've found, frustrating; if at all possible I'd look at using a real debugger (like Chrome's Dev Tools; I've also heard good things about Opera's).
This should help:
http://www.openjs.com/scripts/others/dump_function_php_print_r.php
The easiest way to inspect a javascript variable is with a debugger. If Firebug is not working out for you try using Google Chrome, it has an inspector built in.
Btw - not sure what you mean by "start a debug session". If you have firebug installed, you should simply be able to click on the firebug icon on the bottom right of your browser. Go to the script tab, and select from the drop down whatever js file you want, stick in a break point (just left-click on the margin) and refresh the page. I've never had a problem with Firebug, it's always worked extremely well. I strongly advise figuring out whatever your issue with it is, it will make your life a million times easier.
Using any of the browser dev tools, including IE9, you can use console.log to get the variable output on the console. What information this gives you will vary by browser, but with Firebug it allows you to explore the variable in the DOM inspector tab, with full access to all properties and functions (you can even copy the content of a function to paste elsewhere).
For instance:
var foo = {};
// Do lots of stuff with foo
if (typeof(console) !== "undefined" && console.log) { // prevent errors when console not open, ideally all console calls should be removed before going into production
console.log(foo);
}
This has the advantage that it doesn't require any break points, so no slow step-debugging. It won't solve everything though, you'll often still need the debugger.
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.).