开发者

How can you debug JavaScript which hangs the browser?

开发者 https://www.devze.com 2023-04-01 22:30 出处:网络
I\'m working on a substantially large rich web page JavaScript application. For some reason a recent change is causing it to rand开发者_如何学JAVAomly hang the browser.

I'm working on a substantially large rich web page JavaScript application. For some reason a recent change is causing it to rand开发者_如何学JAVAomly hang the browser.

How can I narrow down where the problem is? Since the browser becomes unresponsive, I don't see any errors and can't Break on next using FireBug.


Instead of commenting the hell out of your code, you should use a debug console log.

You should use the console.log() functionality provided by most modern browsers, or emulate it if you use a browser that doesn't support it.

Every time you call console.log('sometext'), a log entry in the debug console of your browser will be created with your specified text, usually followed by the actual time.

You should set a log entry before every critical part of your application flow, then more and more until you find down what log isn't being called. That means the code before that log is hanging the browser.

You can also write your own personal log function with added functionalities, for example the state of some particular variable, or an object containing a more detailed aspect of your program flow, etc.

Example

console.log('step 1');

while(1) {}

console.log('step 2');

The infinite loop will halt the program, but you will still be able to see the console log with the program flow recorded until before the program halted.

So in this example you won't see "step 2" in the console log, but you will see "step 1". This means the program halted between step 1 and step 2.

You can then add additional console log in the code between the two steps to search deeply for the problem, until you find it.


I'm surprised this hasn't been properly answered yet, and the most voted answer is basically "put console logs everywhere until you figure it out" which isn't really a solution, especially with larger applications, unless you really want to spend all your time copy-pasting "console log".

Anyways, all you need is debugger; someone already mentioned this but didn't really explain how it could be used:

In chrome (and most other browsers), debugger; will halt execution, take you to the dev console, and show you the currently executing code on the left and the stack trace on the right. At the top right of the console there are some arrow like buttons. The first one is "resume script execution". The one we want is the next one "step over next function call".

Basically, all you need to do is put a debugger anywhere in your code, at a point where you know the page hasn't frozen yet, and then run it, and repeatedly click "step over next function call" which looks like an arrow jumping over a circle. It will go line by line, call by call, through the execution of your script until it hangs/gets stuck in an infinite loop. At this point, you will be able to see exactly where your code gets stuck, as well as all the variables/values currently in scope, which should help you understand why the script is stuck.

I was just racking my brain trying to find a hanging loop in some rather complex JS I'm working on, and I managed to find it in about 30 seconds using this method.


You can add debugger; anywhere in your JS code to set a breakpoint manually. It will pause execution and allow you to resume/inspect the code (Firebug/FF).

Firebug Wiki page: http://getfirebug.com/wiki/index.php/Debugger;_keyword


Todays browsers Firefox/Seamonkey (Ctrl-Shift-I / Debugger / PAUSE-Icon), Chrome, ... usually have a builtin JS debugger with PAUSE button which works any time. Simply hit that when on a looping / CPU-intensive page, and most likely the "Call Stack" kind of pane will point you to the problem - ready for further inspection ...


To isolate the problem you could start by removing/disabling/commenting different sections of your code until you have narrowed down the code to a small part which will allow you to find the error. Another possibility is to look at your source control check-in history for the different changes that have recently been committed. Hopefully you will understand where the problem comes from.


Install Google Chrome, go to your page, press f12 and the developer console will popup. Then select the Scripts button, then select your script (ex: myScript.js) from the dropdown in the top-left of the console. Then click on the first line (or a line where you think don't hangs) and a break-point will be made. After the javascript reaches your break-point click on one of the buttons of the top-right of the console (you will see a button like Pause symbol and then other 4 button). Press on the 2º button (or the button after pause to step over) or the 3º button (step in). Mouse over the buttons and they will explain to you what they mean. Then you will go in your code like this until it hangs and then you can debug it better.

Google Chrome debugger is far better than firebug and faster. I made the change from firebug and this is really great! ;)


I know it's primitive, but I like to sprinkle my js code with 'alert's to see how far my code is going before a problem occurs. If alert windows are too annoying, you might setup a textarea to which you can append logs:

<textarea id='txtLog' ...></textarea>

<script>

...
function log(str) {
    $('#txtLog').append(str + '\n');
}
log("some message, like 'Executing Step #2'...");
...

</script>


In my experience, issues which cause the browser to become unresponsive are usually infinite loops or the suchlike.

As a start point, investigate your loops for silly things like not incrementing something you later rely on.

As an earlier poster said, other than that, comment out bits of code to isolate the issue. You 'could' use a divide and conquer methodology and near literally comment out half the pages JS, if it worked with a different error, you've probably found the right bit!.

Then split that in half, etc etc until you find the culprit.


I think you can Use Console Log like this

console.log(new Date() + " started Function Name or block of lines from # to #");

// functions or few lines of code

console.log(new Date() + " finished Function Name or block of lines from # to #")

By the end of running your webpage, you can identify the area that take so much time during executions, b


Besides using manual log output and the debugger it might sometimes be helpful to log each and every function call to track down where the loop occurs. Following snippet from Adding console.log to every function automatically might come in handy to do so ...

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];
        if (typeof fn === 'function') {
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    return fn.apply(this, arguments);

                }
            })(name, fn);
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name);
});


I know this question is old, but in VS2013 and you can press the pause button and get a full JS stack trace. This was driving me crazy because the loop was inside angular, so I couldn't really put in alerts, break points, etc. because I had no idea where to put them. I don't know if it works with the free express edition, but it's worth a shot.

I've also read that Chrome has a pause function, so that could be an option, but I haven't tried it myself.


I ran into same problem and that's how I resolved it.

  1. Check Console for errors and fix them

Some time console even is hanging

  1. Check for all the loops if the one is infinite
  2. Check for recursive code
  3. Check for the code which is dynamically adding elements to document
  4. Use break points in your console
  5. Use some console logging i.e log the suspected code blocks


Something I don't really see in these answers is that you can do e.g.:

let start;
let end;
//This would represent your application loop.
while (true) {
  start = performance.now();

  //Loop code.
  //...

  end = performance.now();
  //Measured in ms.
  if (end - start > 1000) {
    //Application is lagging! Etc.
  }
}

In this manner, you can perhaps detect when your application is starting to perform poorly etc.

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

0

精彩评论

暂无评论...
验证码 换一张
取 消