Javascript - Preventing Chrome From Killing Page during long loop - javascript

Chrome keeps killing the page in the middle of my connect-four browser game when it is running properly. The game is a player vs computer setup and the game itself runs properly and never crashes. The page crashes when I set the number of iterations too high for training the computer opponent. The programs trains the ai using a qLearning algorithm where it plays itself and stores a value for each encountered state. If I set the number of iterations to about 125,000 or less, then everything works fine (except the opponent is not so great). I cannot tell if it is the running time of the loop (would take about 30 minutes to run) that kills the program or something else such as memory constraints for recording states and their corresponding q-values.
How can I get the program to run for more training iterations without chrome killing the page?

You've got a couple of options on how to handle your code.
Option 1: setInterval / setTimeout
As others have suggested, using setInterval or setTimeout can run your code in "chunks" and no one chunk will cause a timeout.
Option 2: setInterval + generators
With deeply nested code, using setTimeout is very difficult to properly re-enter the code.
Read up on generators -- that makes running code in chunks much nicer, but it may take some redesign.
Option 3: webworkers
Webworkers provide another way, depending on what you are calculating. They run in the background and don't have access to the DOM or anything else, but they are great at calcuation.
Option 4: nodejs
Your last option is to move away from the browser and run in another environment such as node.JS. If you are running under Windows, HTA files may be another option.

Related

While true difference between browser and a compiled program on the OS

Today I watched a colleague of my program a small game in Python on his Raspberry Pi. The game engine ran by using a while(true) or infinite loop. I myself use a websocket program in PHP that uses while(true). In these examples a infinite while loop is used which doesn't cause the program to become unresponsive. Without it, it wouldn't work properly. However in JavaScript we need to avoid a infinite loop at all costs. When a loop becomes infinite the browser hangs and becomes unresponsive.
My question: What is the difference between a infinite loop running in a compiled Python program and a infinite loop written in JavaScript running in a browser?
The difference is that the JavaScript runs on the browser's UI thread (preventing it from pumping normal OS messages like paint), whereas the Python program doesn't have a UI, and thus it doesn't matter if the main thread is hogged by your code.
You're still blocking the main thread either way, but in different contexts.
The main diffrence between the Python and the JavaScript code is that the Python code takes care of updating the UI, whereas the JS code just loops it's game logic and is therefore preventing the browser from updating it's view.
When you make a game, you usually put your in a loop where the first call goes to the game logic to update positions, player health, cat count and something like this. After that, you call a render method so that your updated content is processed as a picture and send to the screen. Then you start again. In JavaScript, you omitt the call to the render function and therefore the browser's UI never updates.
This has nothing to do with threading, but in a language like Pyhton (and many others) you can separate the game logic and the rendering so that when your logic is taking a while to do it's cat repositioning the programm is still able to update your screen (with the same, non-updated content over and over but that's another topic).
TL;DR The JavaScript blocks the rendering process of the Browser, whereas the Python loop explicitly calls the rendering function for it's UI.
For JS you should use setInterval(function, time), as #RúnarBerg noted.
EDIT: #mouser noted that you can also use web workers, which seem to be a html5 approach to multi-threading in JS. It may be worth a look if you are developing a game in JS, especially since it's supported in all major browser according to w3schools.
In Python, your loop probably looks like this:
while true:
TakeInput()
DoStuff()
So each iteration of the loop does something, and it keeps doing that forever.
In JavaScript, the input usually comes from the browser. If your JavaScript code is looping forever, the browser never gets a chance to let your code know new input has arrived.
You could write JavaScript code like this:
while (true) {
x = input('Give me input!');
// Process x
alert(result);
}
which would approximate the Python code, but that's not the way JavaScript usually works, and side-steps the browser all together.
Javascript has asynchronous runtime, meaning that your code doesn't usually have to wait for other parts to continue. You can run an infinite non-blocking loop with setInterval(fn, time) which executes the function fn at an interval of time milliseconds.

Javascript Timed Notifications - setTimeout, setInterval

I am creating a web app that allows users to manage a calendar (CRUD events, tasks, reminders etc...)
And I am trying to implement a feature where they will receive a popup reminder x-minutes before the event/task. From my understanding there is really only one way to do this with javascript:
On login, check for any upcoming events in the database (say in the next 12 hours) and create a setTimeout for the next event, when that setTimeout executes, check again for next event and so on...
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
Is there a better way to handle popup notifications on the client side? Push Notifications? Any suggestions would be greatly appreciated!
My question is, will having multiple setTimeouts (10+) running in the background during user interaction slow down the performance of my app?
In those numbers, no. (Depending on how + the + in 10+ is. I mean, I expect a million probably would be an issue.)
The other approach would be to have a single timer that you use (say, per minute) to check for notifications that should occur as of that minute. E.g.:
function notifyForThisMinute() {
// Notify user of things we should notify them of as of this minute
// ...
// Schedule next check for beginning of next minute; always wait
// until we're a second into the minute to make the checks easier
setTimeout(notifyForThisMinute, (61 - new Date().getSeconds()) * 1000);
}
notifyForThisMinute(); // First call starts process
This depends on the browser (or more specifically, it's javascript engine) and apparently even OS.
Neil Thomas (while working on GMAIL mobile) and John Resig have analyzed timers.
One of the more noticeable things to look out for is how often the timer runs per given time-interval (say every 200ms or once every 10 minutes..).
Thomas:
With low-frequency timers - timers with a delay of one second or more - we could create many timers without significantly degrading performance on either [an Android G1 or iPhone 3G]. Even with 100 timers scheduled, our app was not noticeably less responsive. With high-frequency timers, however, the story was exactly the opposite. A few timers firing every 100-200 ms was sufficient to make our UI feel sluggish.
Thomas:
Keep in mind that this code is going to execute many times every second. Looping over an array of registered callbacks might be slightly "cleaner" code, but it's critical that this function execute as quickly as possible. Hardcoding the function calls also makes it really easy to keep track of all the work that is being done within the timer.
Resig:
Once you start moving into the range of 64-128 simultaneous timers, you’re pretty much out of luck in most browsers.
One might also have a look at Chronos

Is there is any way to call a function when an infinite loop or browsser hangs in javascript?

hi i m working a project which have huge javascript code sometimes javascript code executes automaticaly and hangs browser with message "kill this page" in chrome is there is any way to track the error .like calling calling a function when infinite loop arrives or browsser hangs like that .please give me some suggestion about debugging javascript code plz.
There is no way of doing what you wish inside javascript.
However you can use a tool like DynaTrace Ajax Edition to trace cpu usage in the browser to identify what is happening.
Infinite loop can be caused in many different bad programming logic, and there is no reliable logic to detect in every case. So I highly doubt if any programming language or IDE would offer any reliable infinite loop detection.
What you saw was basically a runtime detection based on how long script execution has taken before the browser could update and refresh the UI.
Sometimes this kind of long running JavaScript could be caused by infinite loop, but many times they are just big loops or loops that perform too much work that makes UI unresponsive.
Because JavaScript is not multi-thread, therefore to avoid the later case above, you could consider breaking the loops into small units of work, once a unit is finished, don't run the next unit, but instead call the next unit of work with setTimeout with a small time delay (such as 250ms). This would give the browser a chance to breath and update UI, and unmark your script as "long-running" script.
You may also use logging such as Firebug Logging to log the loops with enough values that help you find out if those loops are indeed infinite loops.

Why is EventMachine so much slower than Node?

In my specific case, at least. Not trying to make general statements here.
I've got this web crawler that I wrote in Node.js. I'd love to use Ruby instead, so I re-wrote it in EventMachine. Since the original was in CoffeeScript, it was actually surprisingly easy, and the code is very much the same, except that in EventMachine I can actually trap and recover from exceptions (since I'm using fibers).
The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine. When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.
I realize that without code you can't really know what exactly is going on, but I was just wondering if there is some kind of underlying difference and I should give up, or if they really should be able to run about as fast (a small slowdown is fine) and I should keep trying to figure out what the issue is.
I did the following, but it didn't really seem to have any effect:
puts "Running with ulimit: " + EM.set_descriptor_table_size(60000).to_s
EM.set_effective_user('nobody')
EM.kqueue
Oh, and I'm very sure that I don't have any blocking calls in EventMachine. I've combed through every line about 10 times looking for anything that could be blocking. All my network calls are EM::HttpRequest.
The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine. When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.
If they're not running in parallel then it's not asynchronous. So you're blocking.
Basically you need to figure out what blocking IO call you've made in the standard Ruby library and remove that and replace it with an EventMachine non blocking IO call.
Your code may not have any blocking calls but are you using 3rd party code that is not your own or not from EM ? They may block. Even something as simple as a debug print / log can block.
All my network calls are EM::HttpRequest.
What about file IO, what about TCP ? What about anything else that can block. What about 3rd party libraries.
We really need to see some code here. Either to identify a bottle neck in your code or a blocking call.
node.js should not be more than an order of magnitude faster then EM.

Maximum execution time for JavaScript

I know both ie and firefox have limits for javascript execution (Source 1, Source 2). Based on number of statements executed, I heard it was 5 million somewhere in IE and based on number of seconds in firefox: it's 10 seconds by default for my version.
The thing I don't get is what cases will go over these limits:
I'm sure a giant loop will go over the limit for execution time
But will an event hander go over the limit, if itself it's execution time is under the limit but if it occurs multiple times?
Example:
Lets say I have a timer on my page, that executes some javascript every 20 seconds. The execution time for the timer handler is 1 second. Does firefox and ie treat each call of the timer function seperatly, so it never goes over the limit, or is it that firefox/ie adds up the time of each call so after the handler finishes, so after 200 seconds on my site (with the timer called 10 times) an error occurs even though the timer handler itself is only 1 second long?
The following article by Nicholas C. Zakas discusses how and when different browsers interrupt long running JavaScript code:
What determines that a script is long-running?
Breaking long processing code into small chunks and launching them with timers is in fact one way to get around this problem. The following Stack Overflow post suggests a method to tackle this:
Show javascript execution progress
On the other hand, web workers would be more suited for long running processing, since their execution happens in a separate process, and therefore does not block the UI thread:
Mozilla Dev Center: Using web workers
John Resig: Computing with JavaScript Web Workers
Nicholas C. Zakas: Experimenting with web workers
However web workers are not supported in Internet Explorer yet, and they would not have access to the DOM.
The event handler is considered a new execution context - the time limit is reset.
If you need to do even more computation, take a look at WebWorkers.
I too stuck in this kind of JS error. I also get the solution, unfortunately only for IE, which tells to edit the registry (regedit command) and update the number of JS commands to allow. Read more here http://support.microsoft.com/?kbid=175500.
But this doesn't seems to be a good solution to me bcoz if you are developing a web application you can not ask every user to use only IE and update his system registry.
As a workaround: If your data to process at client end is really large then you can put some manual delays between fix set of events processing. For ex. If there are 100 events of any task you want to process then you can break them in to 10 sets of 100 and process each of them in say 100ms. To know how to do that follow below link:
http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/

Categories

Resources