console.log的那些事

5,012 阅读5分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

控制台 console.log() 打印很多日志,会不会影响浏览器卡顿?

为什么要写这篇文章,接手了一个老项目,需要对项目的性能进行优化,打开F12发现,console.log()写的内容太多,多到你不敢想象,这还是次要的,上线的代码,debugger,到处都是,整个系统,每天用户使用到下午三四点的时候开始卡顿,CTRL+SHIFT+DELETE之后,速度又快了,种种迹象表明,肯定是有内存泄露的情况,因为是老系统,前后端不分离,首先要说服负责人,上线代码删除console.log, 今天不讲解怎么删除线上代码console.log, 先分析一下,为什么线上代码要删除console.log

console.log() 目的是向浏览器控制台打印信息, 常用来在开发的时候调试分析,但是很多人在上线的代码里面忘记关闭了, 导致打印信息不停的输出。

1) console.log:   可能导致内存泄露

(2) console.log:   在传递给console.log的对象是不能被垃圾回收

(3) console.log:   它属于宏任务,在执行的时候,也是需要耗时

结合Chrome的 F12中的Performance 进行一些分析, 勾选上Memory, 通过带有console.log的输出和没有console.log的输出,对比分析结果: 最好不要在页面中进行console.log的大对象输出,会影响到页面的整体性能。

1, console.time

​ 通常我们查看一段代码的执行时间,用来作性能调试分析所用。

首先记住:console.log 对象不会被浏览器垃圾回收机制回收 会造成浏览器卡顿
console.time()相当于秒表中的开始按钮
console.timeLog()相当于秒表中的按圈计时/按点计时
console.timeEnd()相当于计时结束
console.time('time')
console.log(JSON.parse(JSON.stringify(new Object())))
console.timeEnd('time')
打印:time: 1.572021484375ms
console.time('time')
setTimeOut(() => {
   console.timeEnd('wait')
}, 1000)

wati: 1000ms

2, console.count

这是一个计数器, 传递一个函数的名称,可以打印出这个函数被调用的次数

let a = () => {
     console.count('调用a')
}
let b = () => {
     console.count('调用b')
}
a()
b()
输入: 调用a:1
      调用b:1

3, console.assert

断言, 可以理解为: 才猜错了这个表达式的真假,那我就可以打出我的信息

console.assert(参数1,参数2), 这里面有两个参数:

第一个参数:是断言条件,即应该发生的情况;

第二个参数:是不满足断言条件时,打印出来的提示信息。

console.assert(a === 3, "a 的值不是3!");

断言函数还是挺有用的,就算不是为了做单元测试,自己平时在写代码时为了保证程序正确性,也可以使用一下。可以让我们的输出更加干净。当然,你也可以写if判断语句。

4, console.clear

这个函数也是经常用,在多人开发的项目里面,特别是很多项目小组成员都喜欢打印console.log的时候,你在调试的时候,特别不想看到他们的结果,统统都可以用console.clear清楚干净,那后输出自己的调试信息。

console.clear()
console.log(data)

5, console.dir

在大多数情况下,console.dir()和console.log() 看起来很像,在打印DOM元素信息的时候,你会发现,dir会输出的更加详细

举个列子:查看element信息
let element = document.getElementById('root')

console.log(element)

<div class="root">
   <img class="ssse" src="https:/xxxx">
    <meta itemprop="commentCount" content="24"></meta>
    <div class="ble">
      <div class="Rtr">
        <span class="Rix">Vue</span><span class="p">,</span>
      </div>
    </div
</div>   

console.dir(element)

div#root
accessKey: ""
align: ""
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {0: id, id: id, length: 1}
autocapitalize: ""
baseURI: "https://www.zhihu.com/question/61986999"
childElementCount: 1
childNodes: NodeList [div]
children: HTMLCollection [div]
classList: DOMTokenList [value: ""]
className: ""
clientHeight: 2763
clientLeft: 0
clientTop: 0
clientWidth: 743
contentEditable: "inherit"
dataset: DOMStringMap {}
dir: ""
draggable: false
firstChild: div
firstElementChild: div
hidden: false
id: "root"
innerHTML: "<div><div class="LoadingBar"></div><div><header ro"
inputMode: ""
isConnected: true
isContentEditable: false
lang: ""
lastChild: div
lastElementChild: div
localName: "div"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: script#js-clientConfig
nextSibling: script#

6, console.warn

可以直接替换console.log,他们都是输出,唯一的区别就是:输出的文字颜色是黄色, 具体来说,如果给日志定义错误级别的话,它的输出属于警告级别,而不是信息级别, 使其在众多日志中输出会显示的更加明显,突出

console.warn('这是一个警告')
输出是:黄色字体,这是一个警告⚠️

7, console.log, debugger的区别

这些都可以用来调试。

debuuger: 在指定的代码处,添加debugger, 或者打开浏览器的F12, 在指点的地方添加F12,通过执行项目,一步步观察变量和函数的执行过程

Console.log: 在指点的函数和变量的地方添加console.log, 把向查看的结果dayin 在浏览器控制台上,进行过程分析, 两者都能加快我们的开发

在准确率上来说, console..log的准确率要高于debugger, 因为在我们的代码中,有很多异步事件,也有很多监听方法,或者是生命周期函数,他们的执行顺序或决定这变量值的存储,影响到不同的执行结果,debugger无法查看代码的执行顺序, 可能会给自己带来无法想象的问题,本人就在这个问题上吃过几次亏, 因为打来debugger 会加快一些异步请求的速度,实际上,如果没有这些debugger, 异步请求是没有完成的。这样会导致我们开发的时候,功能都是正常的,为什么上了测试或者上生产就会有问题的原因

个人建议: 简单功能,可以通过浏览器debugger断点查看
         复杂功能,涉及到一些异步请求,事件监听或者是生命周期函数,最好是用console.log就行调试,当然,
         调试完成之后,一定要养成删掉的习惯。

8, 总结

测试通过的代码,即将发到生产环境上的代码,要避免有大量的console.log日志输出,它会影响到页面的性能,有可能会造成内存泄露, 开发的过程中可以养成用console.log的习惯, 在有异步接口请求,或者多个事件监听发送的代码中,尽量不要用debugger排查问题。