在分析 JavaScript 时如何忽略像 jQuery 这样的库?

Posted

技术标签:

【中文标题】在分析 JavaScript 时如何忽略像 jQuery 这样的库?【英文标题】:How can I ignore libraries like jQuery when profiling JavaScript? 【发布时间】:2011-12-05 12:00:19 【问题描述】:

当然,Firebug、Chrome 的 Web Inspector、Opera 的 Dragonfly 和 dynaTrace 的 IE AJAX 工具都具有分析功能。但是,我还没有找到可以让我“忽略”库的工具。

举个例子,假设我有以下纯 JS/DOM 代码:

function foo(node) 
    for (var i = 0; i < node.childNodes.length; i++) 
        node.childNodes[i].innerhtml = 'Test';
    

还有一段类似的使用 jQuery 的代码:

function bar(jqNode) 
    jqNode.children().each(function() 
        $(this).html('Test');
    );

(示例不是很好的代码,请保留它们,因为这不是重点)

如果您通过 JS 分析器将两者都抛出,您会发现在第一个示例中,只有一个函数的“自身时间”等于函数中花费的“总”时间 - 作为 DOM 操作算作“自己的时间”。

然而,在 jQuery 示例中,所有这些都被抽象到 jQuery 中,这意味着“自己的时间”很少,所有时间都花在 jQuery 中。

这使得很难找到性能瓶颈,因为具有最高“自身时间”的函数是 jQuery.fixjQuery.init 等等(这并没有告诉我写得有多好(或不写)我的代码是),并且“总时间”最高的函数通常在调用堆栈中太高而无法找出实际问题出在哪里(如果您有一个函数调用其他 10 个函数,而一个函数需要“永远”,则调用函数将有更大的“总时间”,但这不会让你弄清楚哪个被调用函数花费的时间最长')。

【问题讨论】:

Raynos:使用其他库分析代码会遇到同样的问题。编写自己的包装器来解决浏览器的疯狂和库将为您解决的各种其他问题意味着您正在编写自己的库 - 这仍然会遇到这个问题。我认为你的建议没有帮助。诚然,我给出的示例存在偏差,因为您当然不需要使用 each,但是在没有 querySelector(All) 的情况下轻松访问浏览器中的元素也会遇到同样的问题,而且不是为了得到“圆”。 【参考方案1】:

过滤掉库不是您想要的,AFAIK 没有分析器按照您想要的方式进行。此外,如果你的代码因为滥用库调用而写得不好,你想看看它滥用了哪个库调用。

在“树(自上而下)”模式下使用内置的 Chrome 分析器。 (选择 Self 和 Total 列底部的模式。)在这种模式下,您可以看到每个函数花费的总时间以及函数调用的每个函数所花费的总时间等等,直到调用 no 的叶函数其他功能。因此,在您的函数bar() 中,您将看到在 bar 及以下的总时间,bar 调用 each 所花费的总时间等等。 (现在使用 jQuery 可能会有些复杂,但这不是重点。)

因此,如果您有一个函数调用 10 个其他函数,而一个函数需要“永远”,则调用函数将具有更大的“总时间”,您可以通过单击三角形来确定哪个被调用函数花费的时间最长,然后扩展“永远”函数并查看它调用的每个函数的总时间。如果 9 花费很少的时间,而 1 花费很长时间,那么这就是罪魁祸首,你会继续钻研,直到找到问题所在。

编辑:关于使用 Chrome 分析器的更多提示

使用“Heavy (Bottom up)”视图来查找需要大量时间的叶函数。三角形显示谁打电话给他们。 选项-单击三角形以打开整个树。通过深度嵌套的调用链节省大量点击次数。 “(程序)”是指分析器运行期间没有运行 javascript 的部分时间。诸如渲染 HTML 之类的事情。

您可以针对每个功能进行过滤和关注。阅读the documentation 了解更多详情。

【讨论】:

"(现在使用 jQuery 可能会有些复杂,但这不是重点。)" - 但这正是我的重点。 :-) Chrome 在自上而下模式下的分析器假装它在“程序”中花费了 53% 的时间(说什么?),几乎所有其他功能的自身时间为 0%。最大总时间是最顶层的库函数(jQuery 事件处理)。为了达到我关心的部分,我必须像这样走树:gijsk.com/temp/profiling.png。问题是,这个函数从树的其他部分被调用了无数次。这不是一个有效的解决方案。 (对于上下文,这是对 JS 进行静态分析的代码,使用 AST 行走,因此是可笑的嵌套 - 我关心我的分析代码的速度,而不是行走代码的速度(除非绝对必要,否则我真的不想改变)) @Gijs,显然你的代码很复杂,你感兴趣的只是其中的一小部分,所以你不能指望我完全理解如何让你专注于你想要的东西。不过,我可以向您保证,Chrome 的分析器足以让您得到答案。在您的图像中,您会看到 walkwalkers.stat 之间的总时间下降了 5%。所以walk 中的代码部分在walk 的调用从MAPwalkers.stat 的调用之间转换是一个需要优化的地方。相比之下,您在分析中的代码只是微不足道的时间,无需更改。 @Gijs,您在评论中描述的情况与问题中的情况相反。如果您担心从很多地方调用代码的影响,请使用“Heavy (Bottom Up)”模式。如果您的功能没有出现在该列表中,那是因为它的自身时间在配置文件的总时间中占很小的一部分,以至于它微不足道,这意味着它足够高效。如果您在列表中识别出您的函数调用的函数,则可以单击函数列表底部的 X 按钮将该函数的执行时间分配给其调用者。 我不认为这种情况有所不同。如果您从上到下查看配置文件,它会在库函数树中丢失。如果你从下往上看,它确实迷失了,因为它几乎没有“自我”的时间。但是,该函数的繁重源于其(递归/重复)库调用。如果您查看屏幕截图,您会看到突出显示的功能也显示在该树的顶部附近。 :-) 您对“X”按钮的建议很有趣。这可以自动完成(在源 URL 上吗?)并用于调用图中的“中间”功能,而不仅仅是离开?【参考方案2】:

您尝试过 John Resig 的分析器插件吗?

http://ejohn.org/blog/deep-profiling-jquery-apps/

【讨论】:

该博文中指向实际插件的链接似乎已失效,而且 Google 也没有提供任何有用的替代方案。此外,从外观上看,这个插件可以让你看到哪些 jQuery 方法需要很长时间。我并不特别关心这一点 - 我关心 我的代码 的哪些部分运行缓慢,并且想要修复这些部分。如果这涉及修复 jQuery 代码,那是第二步。它不应该是第一个;我的代码比 jQuery 的代码更愚蠢(低效的选择器等)。【参考方案3】:

您可以尝试使用console.profileconsole.profileEnd 在代码中打开和关闭分析。这些链接指向 Firebug 文档,但至少 Webkit 也支持它。不确定 IE。

【讨论】:

这将创建单独的分析结果,这是非常没用的:我不知道组合这些结果的方法,并且在一个相当复杂的应用程序中,您输入/退出 jQuery 数量级的频率比您自己的函数会被调用,因此会有 很多 分析结果。【参考方案4】:

使用 dynaTrace AJAX 版,您可以在首选项对话框中排除由其 URL 指定的库。在“代理”选项卡中,您可以提供不应跟踪的文件列表。所以如果你在那里列出你的 jquery.js,你不应该在 PurePaths 中看到任何与 jquery 相关的节点......

【讨论】:

事实上,这并不像它在锡上所说的那样。它们仍然出现,只是被列为来自&lt;html&gt; 文件。浏览函数源代码仍然显示原始的jQuery代码,虽然... dynaTrace AJAX 版的开发于 2014 年停止。2014 年的 4.5.0 版仍然可用。最后支持的 Firefox 版本是 34。dynatrace.com/topics/ajax-edition

以上是关于在分析 JavaScript 时如何忽略像 jQuery 这样的库?的主要内容,如果未能解决你的问题,请参考以下文章

javascript:在用户键入或更改文本框值时忽略无效输入[重复]

忽略 Visual Studio 中的代码分析规则

jQuery 选择器忽略页面加载后操作的类

Windows 中的 Python 分析,如何忽略内置函数

如何忽略javascript时区将日期时间发送到服务器

容易忽略的javascript知识点的总结