第四节 js代码优化
文章内容输出来源:拉勾教育Java高薪训练营
1. 简介
- 如何精准测试javaScript性能
- 本质上就是采集大量执行赝本进行数学统计和分析,从而得出一个比对的结果
- 使用基于Benchmark.js的https://jsperf.com完成
- 使用流程
- 填写详细的测试用例信息(title,slug)
- 填写准备代码(DOM操作时经常使用)
- 填写必要有setup(准备工作)与teardown(结束时的销毁工作)代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e5oKQPNk-1606014064001)(https://cdn.nlark.com/yuque/0/2020/png/222679/1590720754921-7109d510-f17e-41ec-ac64-5936b610ea97.png)]
重点是测试代码对比的片段
2. 慎用全局变量
- 全局变量定义在全局执行上下文,是所有作用域链的顶端
- 如果作用域链层级比较深,一层层往上找比较耗时
- 全局执行上下文一直存在于上下文执行栈,直到程序退出
- 如果放到全局,则GC会一遍一遍的扫描,浪费时间
- 如果某个局部作用域出现了同名变量则会遮蔽或污染全局
var i ,str = ''
for (index = 0; index < 1000; index++) {
str += index
}
let str = ''
for (let index = 0; index < 1000; index++) {
str += index;
}
3. 缓存全局变量
将大量采用全局变量缓存起来,提高使用效率
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">add</button>
<button id="btn2">add</button>
<button id="btn3">add</button>
<p>123</p>
<button id="btn4">add</button>
<button id="btn5">add</button>
<button id="btn6">add</button>
<p>456</p>
<button id="btn7">add</button>
<button id="btn8">add</button>
<button id="btn9">add</button>
<script>
function getBtn() {
let btn1 = document.getElementById('btn1')
let btn3 = document.getElementById('btn3')
let btn5 = document.getElementById('btn5')
let btn7 = document.getElementById('btn7')
let btn9 = document.getElementById('btn9')
}
function getBtn2() {
let obj = document
let btn1 = obj.getElementById('btn1')
let btn3 = obj.getElementById('btn3')
let btn5 = obj.getElementById('btn5')
let btn7 = obj.getElementById('btn7')
let btn9 = obj.getElementById('btn9')
}
</script>
</body>
</html>
准备代码中放入body的内容,不包括脚本
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()
5. 避开闭包陷阱
闭包使用不当会造成内存泄漏
function test(func) {
console.log(func());
}
function test2(){
var name = 'log'
return name
}
test(function(){
var name = 'log'
return name
})
test(test2)
6. 避开属性访问方法使用
- js不需要属性的访问方法,所有的属性都是外部可见的
- 使用属性访问方法只会增加一层重定义,没有访问的控制力
function Person() {
this.name = 'xiaoming'
this.age = 18
this.getAge = function() {
return this.age
}
}
const p1 = new Person()
p1.getAge()
function Person() {
this.name = 'xiaoming'
this.age = 18
}
const p1 = new Person()
p1.age
7. For循环优化
缓存数组的长度
var array = []
array[10000] = 'test'
for (let index = 0; index < array.length; index++) {
console.log(array[index]);
}
let length = array.length
for (let index = 0; index < length; index++) {
console.log(array[index]);
}
for (let index = array.length -1; index >= 0 ; index--) {
console.log(array[index]);
}
8. 选择最优的循环方式
for / forEach / forin 三个遍历方式,那个更优
var array = [1,2,3,4,5]
array.forEach(item => {
console.log(item);
})
for (let index = array.length -1; index >= 0 ; index--) {
console.log(array[index]);
}
for (const index in array) {
console.log(array[index]);
}
9. 文档碎片优化节点添加
使用const fragEle = document.createDocumentFragment()创建节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
for (let index = 0; index < 10; index++) {
var op = document.createElement('p')
op.innerHTML = i
document.body.appendChild(op)
}
const fragEle = document.createDocumentFragment()
for (let index = 0; index < 10; index++) {
var op = document.createElement('p')
op.innerHTML = i
fragEle.appendChild(op)
}
document.body.appendChild(fragEle)
</script>
</body>
</html>
10. 克隆优化节点操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id="box1">old</p>
<script>
for (let index = 0; index < 3; index++) {
var op = document.createElement('p')
op.innerHTML = index
document.body.appendChild(op)
}
const oldP = document.getElementById('box1')
for (let index = 0; index < 3; index++) {
var newP = oldP.cloneNode('p')
newP.innerHTML = index
document.body.appendChild(newP)
}
document.body.appendChild(fragEle)
</script>
</body>
</html>
11. 直接量替换 new Object
var a = [1,2,3]
var a1 = new Array
a1[0] = 1
a1[1] = 2
a1[2] = 3