What determines that a script is long-running?

One of the programming barriers that web developers are constantly bumping up against is the dreaded long-running script dialog (also called a runaway script dialog). These frightening dialogs are displayed whenever your JavaScript code takes too long to execute. The cardinal rule of web programming is that a user should never see this dialog, as it indicates a lack of proper JavaScript code architecture. Or to put it in simple terms: your code is trying to do too much.

Brendan Eich, creator of JavaScript, is quoted as saying, “[JavaScript] that executes in whole seconds is probably doing something wrong…” My personal threshold is actually much smaller: no script should take longer than 100ms to execute on any browser at any time. If it takes any longer than that, the processing must be split up into smaller chunks.

Still, few web developers truly understand what triggers the long-running script dialog in various browsers, including myself. So I decided to sit down and figure out under what circumstances you’ll see this dialog. There are basically two different ways of determining that a script is long-running. First is by tracking how many statements have been executed and second is by timing how long the script takes to execute. Not surprisingly, the approach each browser takes is slightly different.

Internet Explorer determines that a script is long-running by the total amount of statements the JScript engine has executed. By default, the value is 5 million statements and can be altered via a registry setting. When your script exceeds this maximum number of statements, you’ll get this dialog:

IE Dialog: A script on this page is causing Internet Explorer to run slowly. If it continues to run, your compute may become unresponsive.

The message, “A script on this page is causing Internet Explorer to run slowly. If it continues to run, your compute may become unresponsive.” is a bit harsh if not technically accurate. The options here are to stop the script or allow it to continue running. Script execution is completely halted while the dialog is being displayed. If you choose to continue running the script, then the executed statement count is reset. You will see the dialog again if the number of statements once again reaches the maximum.

Firefox determines that a script is long-running by timing how long the script engine has been executing code continuously. The default time is set to 10 seconds and can be altered via about:config. Note that the amount of time modal dialogs, such as alerts, are displayed does not count against the script engine execution code. When this execution time has been reached, Firefox displays a dialog with the following message:

Firefox Dialog: A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.

Firefox’s message, “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue,” is a bit more descriptive and arguably less scary than IE’s. The options on this dialog are to stop the script, debug the script, or allow the script to continue. As with Internet Explorer, allowing the script to continue resets the timeout for script execution. The “Debug Script” button only appears if you have Firebug installed and active on the given page; debugging the script takes you into a view of the script that is causing the issue in Firebug.

Safari also uses script engine execution time to determine when a script has become long-running. After some digging around in the WebKit source code, it looks like the default timeout is 5 seconds. When that threshold is reached, the following dialog is displayed:

Safari Dialog: A script on the page [url] is making Safari unresponsive. Do you want to continue running the script, or stop it?

The message here is, “A script on the page [url] is making Safari unresponsive. Do you want to continue running the script, or stop it?” Once again, not terribly ideal for a user to see. You can turn off long-running script detection by selecting Disable Runaway JavaScript Timer under the Develop menu.

Chrome is a bit trickier to track down. The long-running script control seems tied to the crash control of any given tab. I’ve dug through the source code and haven’t been able to figure out the exact limit placed on scripts, but it does appear to be time-based and may be 10 seconds (it’s likely either 5 or 10, to match Safari or Firefox). I’m trying to get in touch with someone on the project to confirm. Nonetheless, a long-running script will result in the following dialog:

Chrome Dialog: The following page(s) have become unresponsive. You can wait for them to become responsive or kill them.

Clearly, the Chrome dialog is a bit more vicious than the other browsers. Clicking on “Wait” results in the page continuing its processing until the next script timeout is reached; clicking on “Kill pages” removes the entire page from memory and it is replaced by a placeholder.

Opera is an interesting case: it doesn’t appear to have a long-running script limit. I ran several tests that completed even after minutes of code execution. During the time, the browser remain mostly responsive, which is impressive. I’m not sure if this approach is a good thing or a bad thing at the moment, but it’s what is implemented.

Regardless of the browser being used, your users should never encounter this dialog. It’s very important to do regular performance testing of the JavaScript in your site or web application before deploying to production. There are numerous tools you can use, such as Firebug’s profiler (Firefox), the YUI Profiler (all browsers), and Internet Explorer 8′s Profiler. You should be looking for any single script execution that takes 100ms or longer on any given browser; those methods involved with such a long execution should be evaluated for performance issues. Make sure you don’t use Chrome as your baseline since its JavaScript execution is orders of magnitude faster than others (same goes for Firefox 3.1 and the latest WebKit nightlies). It’s best to use Internet Explorer as a baseline and then look at other browsers; since IE is often the slowest JavaScript engine, fixing problems for it will certainly fix issues in other browsers as well.

Update (1/9): Added more description around the messages each dialog displays.



  1. Michael  Mahemoff

    Hi Nick, great read, thanks.

    I had a case a while back where I was debugging a recursive function. The bug was causing it to recurse infinitely and Firefox just kept hanging until I had to kill the whole app. I was surprised not to see the dialog appear and it's contrary to the notion that it appears after X seconds.

    Infinite recursion is a relatively rare occurrence, and certainly represents a programming bug, so fortunately is only of limited relevance. It does make me wonder if there are other situations where the dialog doesn't appear.

  2. Nicholas C. Zakas

    Hi Mike,

    It actually seems that recursive functions are a special case. I was digging through some source code and seemed to find some evidence indicating this, but I wasn't able to figure out exactly what's going on. But now I'm curious and will probably do some more research digging into this.

  3. Robert K

    Note that the IE limit of 5M instructions was first put in place back in 1997 as part of IE3 and, I believe, has not been changed in that time.

    As hardware and script engine performance has improved the time it takes to bump into this warning has grown smaller and smaller. While developing my JSLitmus script performance testing tool ( http://www.broofa.com/Tools... ) I found myself getting the script alert w/in 500ms.

    Hopefully IE8 has changed the way this alert gets triggered.

  4. Nicholas C. Zakas

    Hi Robert,

    It was actually implemented in IE 4 and has remained unchanged since that time. Prior to that, IE 3.x used a timer mechanism with a timeout of 5 seconds. Thanks for sharing your tool!

  5. Stuart Langridge

    I actually prefer the IE way (count of statements) to the other browsers (count of runtime). If my machine is very busy or is starved of memory then I'll sometimes get the long-running-script dialog in Firefox for, say, gmail (or sometimes even Firebug!) because it's taking a long time to run even though it's not doing much. A statement count avoids this problem.

  6. Mike

    The slow script error does not seem to be limited to a single script. Run a script once with a button click and there is no error. Run it again by clicking the button a second time and you get the error. So the counter seems to be cumulative in some cases, not limited to a single script. The script in question is a simple for-loop intended to trigger the slow script error, so the instructions per click should be identical.

  7. chispanz

    Is there a way to prevent the message in IE without changing the registry?

Understanding JavaScript Promises E-book Cover

Demystify JavaScript promises with the e-book that explains not just concepts, but also real-world uses of promises.

Download the Free E-book!

The community edition of Understanding JavaScript Promises is a free download that arrives in minutes.