【问题标题】:Will console.log reduce JavaScript execution performance?console.log 会降低 JavaScript 执行性能吗?
【发布时间】:2012-07-11 05:37:03
【问题描述】:

使用调试功能console.log 会降低 JavaScript 执行性能吗?会不会影响生产环境中脚本执行的速度?

是否有一种方法可以从单个配置位置禁用生产环境中的控制台日志?

【问题讨论】:

  • 到目前为止,所有答案都假设您只是在输出字符串消息。记录对象的性能如何,可能具有大型对象结构?例如 console.log(largeObj)?
  • 向控制台输出大量对象可以将 3 秒的页面加载时间缩短为 30 秒。只是一个例子......
  • 一个简单的console.log 需要大约50ms

标签: javascript performance


【解决方案1】:

实际上,console.log 比空函数慢很多。在我的 Chrome 38 上运行 this jsPerf test 会产生惊人的结果:

  • 当浏览器控制台关闭时,调用 console.log 比调用空函数慢约 10000 倍
  • 并且当控制台打开时,调用它的速度会慢 100 000 倍

如果您有合理数量的console.… 调用一次触发(在我安装 Chrome 时需要 2 毫秒,或者控制台打开时需要 20 毫秒),您不会注意到性能滞后。但是,如果您反复将内容记录到控制台——例如,通过requestAnimationFrame 连接它——它可能会使事情变得混乱。

更新:

In this test我还检查了用于生产的自定义“隐藏日志”的想法——有一个保存日志消息的变量,可按需使用。原来是

  • 比原生 console.log大约 1000 倍
  • 如果用户打开他的控制台,显然速度会快 10000 倍。

【讨论】:

  • 当编译器看到一个空函数时,它什么也不执行,因为它看到一行要执行它必须运行该函数。编译器根本不会运行一个空的、未使用的函数作为优化。
  • @SidneyLiebrand 感谢您提供的信息,很高兴知道。不过,第二个测试的结果可以用与console.log 相同的方式进行优化。它们都是产生副作用的函数。
  • console.log 本身并不会以您会注意到的方式真正影响性能,除非您将其绑定到滚动/调整大小处理程序。这些被调用了很多,如果您的浏览器必须以每秒 30/60 倍的速度向控制台发送文本,它会变得很难看。然后有一个 IE 错误,它不允许您在控制台关闭的情况下拥有 console.log :(
  • 你说得对——我的回答中也写了。根据经验,我尝试在生产代码中没有控制台调用。但性能并不是原因——而是因为正如@Ramesh 所写的那样,“外行人很容易阅读你的日志”。
  • logging-on x 3,179 ops/sec ±2.07% (56 runs sampled)logging-off x 56,058,330 ops/sec ±2.87% (56 runs sampled)logging-off-stringify x 1,812,379 ops/sec ±3.50% (58 runs sampled)log-nothing x 59,509,998 ops/sec ±2.63% (59 runs sampled)
【解决方案2】:

如果您打算在公共网站或其他地方使用此功能,任何对使用开发人员工具知之甚少的人都可以阅读您的调试消息。根据您记录的内容,这可能不是理想的行为。

最好的方法之一是将console.log 包装在您的一种方法中,您可以在其中检查条件并执行它。在生产版本中,您可以避免使用这些功能。这个Stack Overflow question 详细讨论了如何使用Closure compiler 来做同样的事情。

所以,回答你的问题:

  1. 是的,它会降低速度,虽然可以忽略不计。
  2. 但是,不要使用它,因为它太容易让别人阅读您的日志。
  3. this question 的答案可能会为您提供有关如何将它们从生产中删除的提示。

【讨论】:

  • 请注意 - 使用console.log 记录对象确实会导致内存泄漏,因为浏览器保留了对象结构以允许开发人员扩展日志。
  • “一个人阅读你的日志太容易了”——这是怎么回事?是 JavaScript,他们已经可以完全访问源代码了!
  • @Quentin 确实可以访问源代码,但真正的风险是在执行代码时出现,因为可能正在处理敏感数据(例如来自数据库的个人客户数据)后端)。我的组织(以及许多其他组织)的最佳实践是永远不要在生产代码中使用 console.log。
  • 只是插话:我刚刚发现,即使使用相同的静态文本(没有对象或数组;实际上只是 console.log('test') 会这样做)向 console.log 发送垃圾邮件也会导致性能受到打击。当我在重新渲染期间在数百个 React 组件上调用的函数中记录“调用”时,这引起了我的注意。在频繁更新期间,仅存在日志记录代码就会导致非常明显的卡顿。
【解决方案3】:
const DEBUG = true / false
DEBUG && console.log('string')

【讨论】:

  • 多么优雅的解决方案!
  • 缺少分号 ;)
【解决方案4】:

将使用调试功能console.log减少JavaScript 执行性能?会不会影响脚本的执行速度 生产环境?

当然,console.log() 会降低程序的性能,因为它需要计算时间。

有没有办法在生产中禁用控制台日志 来自单个配置位置的环境?

将此代码放在脚本的开头,以将标准 console.log 函数覆盖为空函数。

console.log = function () { };

【讨论】:

  • 这似乎是在生产环境中禁用控制台日志的最简单的解决方案之一。想知道为什么它没有更多的关注!我们可以在一个变量下控制这个空函数的定义,我们可以根据我们正在使用的环境(产品或开发)切换为真/假
  • 这真是一个绝妙的答案!谢谢!
【解决方案5】:

如果您在通用核心脚本中创建控制台快捷方式,例如:

var con = console;

然后在整个代码中使用 con.log("message") 或 con.error("error message"),在生产环境中,您可以简单地将核心位置中的 con 重新连接到:

var con = {
    log: function() {},
    error: function() {},
    debug: function() {}
}

【讨论】:

  • 肮脏的方式:console.log = function(){}
【解决方案6】:

任何函数调用都会略微降低性能。但是几个console.log应该不会有什么明显的效果。

但是它会在不支持console的旧浏览器中抛出未定义的错误

【讨论】:

    【解决方案7】:

    对性能的影响很小,但在旧浏览器中,如果用户浏览器控制台未打开log is not a function of undefined,则会导致 JavaScript 错误。这意味着 console.log 调用之后的所有 JavaScript 代码都不会执行。

    您可以创建一个包装器来检查window.console 是否为有效对象,然后在包装器中调用console.log。像这样简单的东西会起作用:

    window.log = (function(console) {
        var canLog = !!console;
        return function(txt) {
            if(canLog) console.log('log: ' + txt);
        };
    })(window.console);
    
    log('my message'); //log: my message
    

    这是一个小提琴:http://jsfiddle.net/enDDV/

    【讨论】:

      【解决方案8】:

      我做了这个 jsPerf 测试:http://jsperf.com/console-log1337

      它似乎不会比其他函数调用花费更长的时间。

      没有控制台 API 的浏览器怎么办?如果您需要使用 console.log 进行调试,您可以在生产部署中包含一个脚本来覆盖控制台 API,就像 Paul 在他的回答中建议的那样。

      【讨论】:

      • 如果我可以选择两个答案,这将转到顶部
      • 你的测试不仅增加了console.log调用,还执行了两次相同的jquery操作。我为您的测试创建了以下修订版,希望对您有所帮助:jsperf.com/console-log1337/7 PS:谢谢,我不知道 jsperf.com :)
      • 它实际上似乎比普通的函数调用慢了很多。在直接决斗中,结果是无与伦比的:jsperf.com/console-log1337/14
      • 错误答案。甚至没有远程正确。一厢情愿的投票,@tomekwi 证明了差异是显着的。我自己已经完成了几次真实世界的测试,并且可以毫无疑问地说垃圾邮件 console.log 肯定会导致性能下降。每隔一两秒就会在这里和那里记录一些日志,没什么大不了的,但会经常记录一些东西(帧更新、大量组件的重新渲染),并且有无 console.log 的区别是白天和黑夜。
      【解决方案9】:

      我这样做是为了维护控制台方法的原始签名。在一个公共位置,在任何其他 JS 之前加载:

      var DEBUG = false; // or true 
      

      然后在整个代码中

      if (DEBUG) console.log("message", obj, "etc");
      if (DEBUG) console.warn("something is not right", obj, "etc");
      

      【讨论】:

        猜你喜欢
        • 2018-12-12
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 2020-06-02
        • 1970-01-01
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        相关资源
        最近更新 更多