如何调试挂起浏览器的JavaScript?

时间:2011-09-02 22:49:50

标签: javascript debugging browser

我正在开发一个体积庞大的丰富网页JavaScript应用程序。由于某种原因,最近的更改导致它随机挂起浏览器。

如何缩小问题所在?由于浏览器没有响应,我没有看到任何错误,也无法Break on next使用FireBug。

13 个答案:

答案 0 :(得分:40)

您应该使用调试控制台日志,而不是对代码进行评论。

您应该使用大多数现代浏览器提供的console.log()功能,或者如果您使用不支持它的浏览器,请模拟它。

每次调用console.log('sometext')时,将使用指定的文本创建浏览器调试控制台中的日志条目,通常后跟实际时间。

您应该在应用程序流的每个关键部分之前设置一个日志条目,然后越来越多,直到找到未调用的日志。这意味着该日志之前的代码挂起了浏览器。

您还可以编写具有附加功能的个人日志功能,例如某个特定变量的状态,或包含程序流程更详细方面的对象等。

示例

console.log('step 1');

while(1) {}

console.log('step 2');

无限循环将暂停程序,但在程序暂停之前,您仍然可以看到记录程序流的控制台日志。

因此,在此示例中,您将不会在控制台日志中看到“步骤2”,但您将看到“步骤1”。这意味着程序在步骤1和步骤2之间停止。

然后,您可以在两个步骤之间的代码中添加其他控制台日志,以深入搜索问题,直到找到它为止。

答案 1 :(得分:16)

您可以在JS代码中的任何位置添加debugger;来手动设置断点。它将暂停执行并允许您恢复/检查代码(Firebug / FF)。

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

答案 2 :(得分:7)

我很惊讶这还没有得到妥善的回答,而且投票最多的答案基本上是把控制台日志放到任何地方,直到你弄明白为止#34;这不是一个真正的解决方案,特别是对于更大的应用程序,除非你真的想把所有的时间花在复制粘贴和#34; console log"。

无论如何,你所需要的只是debugger;某人已经提到了这一点,但没有真正解释如何使用它:

在chrome(和大多数其他浏览器)中,debugger;将暂停执行,将您带到开发控制台,并向左显示当前正在执行的代码,右侧显示堆栈跟踪。在控制台的右上方有一些像按钮一样的箭头。第一个是"恢复脚本执行"。我们想要的是下一个"跳过下一个函数调用"。

基本上,您需要做的就是将调试器放在代码中的任何位置,在您知道页面尚未冻结的位置,然后运行它,然后重复单击"跳过下一步函数调用"看起来像一个箭头跳过一个圆圈。它将逐行,逐个调用,通过执行脚本直到它挂起/卡在无限循环中。此时,您将能够确切地看到代码被卡住的位置,以及当前范围内的所有变量/值,这可以帮助您理解脚本卡住的原因。

我只是绞尽脑汁试图在一些相当复杂的JS中找到一个悬挂循环,我正在使用这种方法在大约30秒内找到它。

答案 3 :(得分:6)

要解决问题,您可以先删除/禁用/注释代码的不同部分,然后将代码缩小到一小部分,以便找到错误。另一种可能性是查看最近提交的不同更改的源代码管理签入历史记录。希望你能理解问题的来源。

答案 4 :(得分:3)

安装Google Chrome ,转到您的页面,按 f12 ,系统会弹出开发人员控制台。然后从控制台左上角的下拉列表中选择脚本按钮,然后选择选择脚本(例如:myScript.js)。然后单击第一行(或您认为不挂起的行),将会生成断点。在javascript到达您的断点后,单击控制台右上角的其中一个按钮(您将看到一个按钮,如Pause符号,然后是其他4个按钮)。 按2º按钮(或暂停后按钮跳过)或3º按钮(步入)。将鼠标悬停在按钮上,他们会向您解释它们的含义。 然后你会像这样进入你的代码,直到它挂起然后你可以更好地调试它。

Google Chrome调试器远比firebug好,而且速度更快。我从萤火虫做了改变,这真的很棒! ;)

答案 5 :(得分:3)

今天的浏览器Firefox / Seamonkey(Ctrl-Shift-I / Debugger / PAUSE-Icon),Chrome,...通常都有一个带有PAUSE按钮的内置JS调试器,可以随时使用。简单地在循环/ CPU密集型页面上点击它,并且很可能是" Call Stack"窗格类型将指出您的问题 - 准备好进一步检查...

答案 6 :(得分:1)

根据我的经验,导致浏览器无响应的问题通常是无限循环或类似的。

作为一个起点,调查你的循环是否有愚蠢的事情,比如不再增加你后来依赖的东西。

正如之前的一张海报所说,除此之外,请注释掉一些代码以隔离问题。你可以“使用分而治之的方法,并且几乎可以在半页面上注释掉JS,如果它有不同的错误,你可能找到了合适的位置!”

然后把它分成两半等等,直到找到罪魁祸首。

答案 7 :(得分:1)

我知道这是原始的,但我喜欢用'alert'来我的js代码,看看我的代码在出现问题之前会走多远。如果警报窗口太烦人,您可以设置一个可以附加日志的textarea:

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

<script>

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

</script>

答案 8 :(得分:0)

我知道这个问题很老,但是在VS2013中你可以按下暂停按钮并获得一个完整的JS堆栈跟踪。这让我疯狂,因为循环是在角度内,所以我无法真正发出警报,断点等等,因为我不知道把它们放在哪里。我不知道它是否适用于免费快递版,但它值得一试。

我还读到Chrome有暂停功能,所以这可能是一个选项,但我自己没有尝试过。

答案 9 :(得分:0)

我认为您可以像这样使用控制台日志

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 #")

在运行网页结束时,您可以确定执行期间花费大量时间的区域,b

答案 10 :(得分:0)

我遇到了同样的问题,而且我是如何解决的。

  1. 检查控制台是否存在错误并进行修复
  2. 有些时间控制台甚至挂了

    1. 检查所有循环是否为无限
    2. 检查递归代码
    3. 检查动态添加元素到文档的代码
    4. 在控制台中使用断点
    5. 使用某些控制台记录,即记录可疑代码块

答案 11 :(得分:0)

除了使用手动日志输出和debugger之外,有时记录每个函数调用以跟踪发生循环的位置有时可能会有所帮助。遵循Adding console.log to every function automatically中的摘录可以很方便...

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);
});

答案 12 :(得分:0)

在这些答案中我没有真正看到的是您可以执行以下操作:

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.
  }
}

通过这种方式,您也许可以检测到应用程序何时开始表现不佳等。

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