19

console:向web开发控制台打印一条消息,常用来在开发时调试分析。有时在开发时,需要打印一些对象信息,但发布时却忘记去掉console.log语句,这可能造成内存泄露。

在传递给console的对象是不能被垃圾回收 ♻️,因为在代码运行之后需要在开发工具能查看对象信息。所以最好不要在生产环境中console任何对象。

场景

实际开发中会遇到很多使用console的场景,有些场景例如项目信息和测试环境埋点数据等console信息根据实际情况会需要保留,其余的调试信息则需要及时清除。

  • 项目信息

    • image.png
  • 埋点数据

    • image.png
  • console.table 表格

    • image.png
  • console.time / console.timeLog / console.timeEnd 计时

    • image.png
  • console.trace 堆栈跟踪

    • image.png
  • 接口数据等。。。

实例

log.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Leaker</title>
</head>

<body>
  <input type="button" value="click">
  <script>
    !function () {
      function Leaker() {
        this.init();
      };
      Leaker.prototype = {
        init: function () {
          this.name = '*'.repeat(1e5);
          console.log("Leaking an object %o: %o", (new Date()), this); // this对象不能被回收
        }
      };
      document.querySelector('input').addEventListener('click', function () {
        new Leaker();
      }, false);
    }()
  </script>
</body>

</html>

这里结合Chrome的Devtools–>Performance做一些分析,操作步骤如下:

  1. 开启Performance的记录
  2. 执行CG按钮,创建基准参考线
  3. 多次点击【click】按钮,新建Leaker对象
  4. 执行CG按钮
  5. 停止记录

clipboard.png

可以看出【JS Heap】线最后没有降回到基准参考线的位置,显然存在没有被回收的内存。如果将代码修改为

// console.log("Leaking an object %o: %o", (new Date()), this);

重复上述的操作步骤,分析结果如下:

clipboard.png

从对比分析结果可知,console打印的对象是不会被垃圾回收器回收的。

结论

因此最好不要在页面中console.log任何对象,包括warn、error等兄弟,这样可能会影响页面的整体性能,特别在生产环境中,这些细节需要特别的关注。

避免

如何使用工具避免console?

  • 使用eslint.no-console + husky在提交阶段阻止,上述场景中需要保留console的情况可以用.eslintignore文件或/* eslint-disable */
  • 使用TerserPlugin.drop_console在打包阶段删除

彩蛋

想实现上述场景中项目信息的效果?试试以下console代码

const style1 = [
  'color: #fff',
  'background: #848484',
  'padding: 1px',
  'border-radius: 3px 0 0 3px'
].join(';');
const style2 = [
  'color: #fff',
  'background: #1890FF',
  'padding: 1px',
  'border-radius: 0 3px 3px 0'
].join(';');
console.log('%c NODE_ENV %c production ', style1, style2);
console.log('%c BUILD_TIME %c %s ', style1, style2, new Date().toLocaleString());

小皇帝James
600 声望7 粉丝

IT吴彦祖