JavaScript性能优化(内存管理中的代码优化)

文章说明:本文章为拉钩大前端训练营所做笔记和心得,若有不当之处,还望各位指出与教导,谢谢 ! 

一、避开闭包陷阱 

闭包特点

  • 外部具有指向内部的引用
  • 在‘‘外’’部作用域访问“内部”作用域的数据
function foo(){
    var name = 'lg'
    function fn(){
        console.log(name)
    }
    return fn
}

var a = foo()
a()
  • 闭包是一种强大的语法
  • 闭包使用不当很容易出现内存泄漏,一旦内存出现泄漏,如果不在意,等它不断的泄漏时,会影响整个程序的性能
  • 不要为了闭包而闭包
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
    <title>闭包陷阱</title> 
</head> 
<body>
    <button id="btn">
        Add
    </button>
<script type="text/javascript">
//    function foo(){ //由于闭包语法的存在,里面有些变量是无法回收的,在这种情况下,这种操作很多的时候,内存会越来越多
//        var el = document.getElementById('Btn')
//        el.onclick = function(){
//            console.log(el.id)
//        }
//    }

//    foo()

   function foo(){
       var el = document.getElementById('Btn')
       el.onclick = function(){
           console.log(el.id)
       }
       el = null//若是将DOM中button的节点删除之后,DOM中对document的引用消失了,把el置空之后,该函数对document的引用也消失了,这样的空间就会得以释放
   }

   foo()
</script> 
</body> 
</html>

 二、避免属性访问方法使用 

JavaScript中的面向对象

  • JS不需属性的访问方法,所有属性都是外部可见的
  • 使用属性访问方法只会增加一层重定义,没有访问的控制力
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//直接对属性名称进行访问

 三、For循环优化

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
    <title>For循环优化</title> 
</head> 
<body>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
    <p class="btn">add</p>
<script type="text/javascript">
var aBtns = document.getElementsByClassName('btn')

for(var i = 0;i < aBtns.length;i++){
    console.log(i);
}

for(var i = 0,len = aBtns.length;i < aBtns.length;i++){//不需要像上面代码一样,每次都需要重新获取长度
    console.log(i)
}
</script> 
</body> 
</html>

 

 四、选择最优的循环方法

对数组进行遍历时,性能最好的forEach,其次是for,最后是for in

var arrList = new Array(1,2,3,4,5)
//三种不同的方式对同一数组进行遍历
arrList.forEach(function(item){
    console.log(item)
})

for(var i = arrList.length;i;i--){
    console.log(arrList[i])
}

for(var i in arrList){
    console.log(arrList[i])
}

//对数组进行遍历时,性能最好的forEach,其次是for,最后是for in

 

五、文档碎片优化节点添加

节点的添加操作必然会有回流和重绘,对性能的消耗比较大:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
    <title>优化节点添加</title> 
</head> 
<body>
    <button id="btn">
        Add
    </button>
<script type="text/javascript">
    for(var i = 0;i < 10;i++){
        var oP = document.createElement('p')
        oP.innerHTML = i
        document.body.appendChild(oP)
    }
//第二种优化的方式创建节点
    const fragEle = document.createDocumentFragment()//定义一个文档碎片的容器
    for(var i = 0;i < 10;i++){
        var oP = document.createElement('p')
        oP.innerHTML = i
        fragEle.body.appendChild(oP)
    }

    document.body.appendChild(fragEle)
</script> 
</body> 
</html>

采用文档碎片创建节点,效率更高一些 

六、克隆优化节点操作

代码演示:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
    <title>克隆优化节点操作</title> 
</head> 
<body>
    <p id="box1">old</p>
<script type="text/javascript">
    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.innderHTML = i;
        document.body.appendChild(newP)
    }
</script> 
</body> 
</html>

 七、直接量替换Object操作

当我们定义对象或数组的时候,我们可以用new 的方式来获取相应数据,但是也可以直接采用字面量


var a = [1,2,3]

var a1 = new Array(3)
a1[0] = 1
a1[1] = 2
a1[2] = 3

猜你喜欢

转载自blog.csdn.net/weixin_41962912/article/details/110222101