如何精准测试JS的性能,通过https://jsbench.me/
1.慎用全局变量
- 全局变量定义在全局执行上下文,是所有作用域链的顶端
- 全局执行上下文一直存在于上下文执行栈,直到程序退出
-
如果某个局部作用域出现了同名变量,则会遮蔽或污染全局
这就是全局变量与局部变量的性能对比,由于全局变量在作用域链的顶端,所以查找时间就变长了
2.缓存全局变量
将使用中无法避免的全局变量缓存到局部
getBtn2将全局变量缓存至函数内部,通过jsperf发现getBtn2的性能提升
4.通过原型对象添加附加方法
var fn1 = function() {
this.foo = function() {
console.log(11111)
}
}
let f1 = new fn1()
// 通过原型对象添加附加方法, 效率更高
var fn2 = function() {}
fn2.prototype.foo = function() {
console.log(11111)
}
let f2 = new fn2()
直接添加到构造函数中会在初始化实例的时候初始化此f1函数,不符合高效的标准所以都会添加到原型上,
在prototype上的方法只会初始化一次,可以提供给所有实例使用,符合节省内存开销的标准,所以一般都会添加到原型对象。
5.避免属性访问方法使用
function Person() {
this.name = 'icoder'
this.age = 18
this.getAge = function() {
return this.age
}
}
const p1 = new Person()
const a = p1.getAge()
// 直接访问
function Person() {
this.name = 'icoder'
this.age = 18
}
const p2 = new Person()
const b = p2.age
直接访问的效率更高,JS不需要设置属性访问方法,所有属性都是外部可见的。
6.For循环优化
减少循环体中活动,把循环体中重复的事情抽离到外面去
for (var i = 0; i < arrList.length; i++) {
console.log(arrList[i])
}
// 长度变量可以提前保存
for (var i = 0 ,var len = arrList.length; i < len; i++) {
console.log(arrList[i])
}
采用最优的循环方式
文档碎片优化节点添加
节点的添加操作必然会有回流和重绘
for (var i = 0; i < 10; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
document.body.appendChild(oP)
}
通过createDocumentFragment,文档碎片容器,一次性添加
const fragEle = document.createDocumentFragment()
for (var i = 0; i < 10; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
fragEle.appendChild(oP)
}
document.body.appendChild(fragEle)
克隆优化节点操作
比如你想添加一个p标签,此时文档中已经有了一个p标签,样式和内容和你想添加的差不多,所以可以通过克隆操作提高效率
for (var i = 0; i < 3; i++) {
var oP = document.createElement('p')
oP.innerHTML = i
document.body.appendChild(oP)
}
// 通过克隆方式
var oldP = document.getElementById('box1')
for (var i = 0; i < 3; i++) {
var newP = oldP.cloneNode(false)
newP.innerHTML = i
document.body.appendChild(newP)
}
直接量替换new Object
var a1 = new Array(3)
a1[0] = 1
a1[1] = 2
a1[2] = 3
// 直面量效率高
var a = [1, 2, 3]
堆栈中JS执行过程
优化就是从JS执行过程中,找出可以优化的点,无外乎就是,作用域链查找的层级,当前内存是否释放等
减少判断层级
通过提前return,减少嵌套层级
提前return不仅速度提升,且代码更整洁易读。
减少作用域链查找层级
拿空间换时间
减少数据读取次数
访问对象的属性时,可以提前将属性缓存
字面量与构造式
因为字面量是直接在内存开辟空间,第一种方法又涉及了构造函数和查找对象等