console:向web开发控制台打印一条消息,常用来在开发时调试分析。有时在开发时,需要打印一些对象信息,但发布时却忘记去掉console.log语句,这可能造成内存泄露。
在传递给console的对象是不能被垃圾回收 ♻️,因为在代码运行之后需要在开发工具能查看对象信息。所以最好不要在生产环境中console任何对象。
场景
实际开发中会遇到很多使用console的场景,有些场景例如项目信息和测试环境埋点数据等console信息根据实际情况会需要保留,其余的调试信息则需要及时清除。
项目信息
埋点数据
console.table 表格
console.time / console.timeLog / console.timeEnd 计时
console.trace 堆栈跟踪
- 接口数据等。。。
实例
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做一些分析,操作步骤如下:
- 开启Performance的记录
- 执行CG按钮,创建基准参考线
- 多次点击【click】按钮,新建Leaker对象
- 执行CG按钮
- 停止记录
可以看出【JS Heap】线最后没有降回到基准参考线的位置,显然存在没有被回收的内存。如果将代码修改为
// console.log("Leaking an object %o: %o", (new Date()), this);
重复上述的操作步骤,分析结果如下:
从对比分析结果可知,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());
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。