如何在浏览器中调试内存泄漏、无限循环和执行 Javascript?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5094595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 15:56:01  来源:igfitidea点击:

How do I Debug Memory Leaks, Infinite Loops, and Executing Javascript in the Browser?

javascriptdebugging

提问by Lance Pollard

What are the recommended ways to check for infinite loops in javascript in the browser? Say I open Chrome and it crashes, is there a way to breakpoint or somehow pinpoint where that occurred?

在浏览器中检查 javascript 中的无限循环的推荐方法是什么?假设我打开 Chrome 并崩溃了,有没有办法断点或以某种方式查明发生的位置?

Then I'm wondering, how do I see a running list of the executing scripts in the browser (say some timer I lost track of is running and it's slowing things down)? Preferably in Chrome/Safari, but Firefox would work too.

然后我想知道,如何在浏览器中查看正在执行的脚本的运行列表(比如我忘记的某个计时器正在运行并且它正在减慢速度)?最好在 Chrome/Safari 中使用,但 Firefox 也可以使用。

I use the element inspector/console all the time, I just haven't figured out ways to effectively debug these 3 things.

我一直在使用元素检查器/控制台,只是还没有想出有效调试这 3 件事的方法。

Thanks!

谢谢!

采纳答案by voidvector

For a script that crashes the browser, you can insert a breakpoint anywhere in your code before it crashes. Then just manually step through all the code until it crashes. If you are unable to insert the breakpoint before the browser crashes, you can add the "debugger;" statement somewhere in your code. That basically inserts the breakpoint at that point in the code.

对于使浏览器崩溃的脚本,您可以在代码崩溃之前在代码的任何位置插入断点。然后只需手动单步执行所有代码,直到它崩溃。如果无法在浏览器崩溃前插入断点,可以添加“调试器”;代码中某处的语句。这基本上是在代码中的那个点插入断点。

One way to see what's being run from your JS is to profile it. All the dev tools come with a profiler. Just profile your code for a few seconds after the page loads, and it would give you a glimpse of what's still running. If you are using a library such as jQuery, you would see a lot of internal jQuery functions and some of your own. Look at the function that takes the most running time (per call) and try to minimize their usage, as those are the most costly.

查看 JS 正在运行的内容的一种方法是对其进行概要分析。所有开发工具都带有分析器。只需在页面加载后几秒钟分析您的代码,它就会让您一瞥仍在运行的内容。如果您使用诸如 jQuery 之类的库,您会看到许多内部 jQuery 函数和一些您自己的函数。查看花费最多运行时间(每次调用)的函数并尽量减少它们的使用,因为它们的成本最高。

If you have an infinite loop in the "non-threaded" JS, then your page wouldn't load fully at all. Firefox should tell you the script is taking long time to load and let you debug it (which would show you where it is). For "threaded" JS (ones that's run from a callback or setTimeout), you could track them with the profiler.

如果您在“非线程”JS 中有一个无限循环,那么您的页面根本不会完全加载。Firefox 应该告诉你脚本需要很长时间才能加载并让你调试它(这会告诉你它在哪里)。对于“线程”JS(从回调或 setTimeout 运行的那些),您可以使用分析器跟踪它们。

回答by Alexey Lebedev

1. Memory leaks

1. 内存泄漏

2. Inifinite loops

2. 无限循环

I don't exactly understand what the browser could point you to in the case of complex infinite loop spreading across hundreds of functions. Sure, I'd love the browser to pinpoint simple loops like some function not returning for 15 seconds. But at least we have something, browser tells you a) that script is running slow, and b) what functions were called and how much time each one took. Also, you can set a breakpoint and watch it run step by step.

在复杂的无限循环扩展到数百个函数的情况下,我不完全理解浏览器可以指向您的内容。当然,我希望浏览器能够精确定位一些简单的循环,比如某些 15 秒内不返回的函数。但至少我们有一些东西,浏览器会告诉你 a) 脚本运行缓慢,b) 调用了哪些函数以及每个函数花费了多少时间。此外,您可以设置断点并逐步观察它的运行。

3. Monitoring timers and intervals

3.监控定时器和间隔

Open WebKit's timeline panel, hit "Record" and monitor everything you might want to know about each timer and interval. If you're not using WebKit you can code something simple yourself:

打开 WebKit 的时间线面板,点击“记录”并监控您可能想知道的关于每个计时器和间隔的所有信息。如果您不使用 WebKit,您可以自己编写一些简单的代码:

_setTimeout = setTimeout
setTimeout = function(fn, time) {
  var timeout = _setTimeout(function() {
    console.log('Timeout #' + timeout + ' fired on ' + (fn.name || 'anonymous'))
    fn()
  }, time)
  return timeout
}

Usually I simply make document.title blink when timeout/interval fires.

通常我只是在超时/间隔触发时让 document.title 闪烁。

4. General code performance

4. 通用代码性能