目录
性能测试工具的介绍
- 使用流程
JS代码优化
- 慎用全局变量
- 缓存全局变量
- 通过原型新增方法
- 避开闭包陷阱
- 避免属性访问方法使用
- for循环优化
- 选择最优的循环方法
- 节点添加优化
- 克隆优化节点操作
- 直接量替换 new Object
性能测试工具的介绍
性能工具可以辅助我们知道如何写代码是更高效的,其本质上就是采集大量的执行样本进行数学统计和分析。
- 使用基于
Benchmark.js
的 jsperf.com 完成,目前这个网站一直502
,感兴趣可以本地部署npm i benchmark --save-dev
一下瞅瞅 - 代替网站可以使用 jsbench.me
使用流程(因为一直502目前没有使用过)
- 登录
- 填写详细的测试用例信息(
title
/slug
是短名称,会生成一个网址,因此不可与别人的重复。) - 填写准备代码(
DOM
操作时经常使用) - 填写必要有
setup
(启动操作)与teardown
(执行完成后销毁操作)代码
JS代码优化
代码优化的种类很多,先简单介绍几个,这也是一个积累的过程,以后有遇到的就在这里面增加
慎用全局变量
为什么要慎用?
- 全局变量定义在全局执行上下文,是所有作用域链的顶端。每次查找的时候都从局部找到最顶端,时间会有所消耗。
- 全局执行上下文一直存在于上下文执行栈,直到程序退出,内存空间浪费。
- 如果某个局部作用域出现了同名变量则会遮蔽或污染全局。
下图不看功能,只是想说明用全局变量和不用全局变量的差别:
缓存全局变量
将使用中无法避免的全局变量缓存到局部,下面可以看到缓存过的比没有缓存过的性能要有所提高。
通过原型新增方法
尽量在原型对象上新增实例对象需要的方法,而不是在构造函数内部添加方法。
避开闭包陷阱
闭包可以在外部作用域访问函数内部作用域的数据。
- 闭包是一种强大的语法
- 闭包使用不当很容易出现内存泄露
- 不要为了闭包而闭包
实例分析
下面代码形成了一个闭包,el
存在foo
函数的作用域里面,而onclick
指向的匿名函数又是一个新的作用域,里面引用了foo
作用域中的id
,会导致内存泄露。
function foo() {
var el = document.getElementById('btn')
el.onclick = function() {
console.log(el.id)
}
}
foo()
想要内存不泄露,使用完之后将el
置为null
function foo() {
// 等号右边的代码本来就存在于`DOM`树上,`el`是一个新的引用。
// 这个元素被我们引用了两次。就算`DOM`被`remove`掉了,但是代码`el`中也会引用,只能在下面把代码进行手动清除。
var el = document.getElementById('btn')
el.onclick = function() {
console.log(el.id)
}
// 如果想要不泄露,就添加下面这个
el = null
}
foo()
避免属性访问方法使用
JavaScrip
t中的面向对象中
JS
不需要属性的访问方法,所有属性都是外部可见的- 属性访问方法只会增加一层重定义,没有访问的控制力
for循环优化
把数组的length
也存放到一个变量上。
选择最优的循环方法
forEach
、for
、for-in
的比较
节点添加优化
节点的添加操作必然会有回流和重绘
document.createdocumentfragment()
方法创建了一虚拟的节点对象,是一段新的文档片段,该对象包含所有属性和方法。
这样可以合并节点的添加操作,减少DOM
的重绘。
克隆优化节点操作
已经有的属性和内容不用再次添加
直接量替换 new Object
当我们定义对象和数组的时候,我们可以用new
,也可以采用字面量。