JavaScript 성능 최적화 2 (코드 최적화)

기사 설명 : 본 기사는 레가 오 프론트 엔드 트레이닝 캠프의 경험담입니다. 뭔가 잘못된 점이 있으면 지적 해주시고 가르쳐 주시길 바랍니다. 감사합니다! 

하나, JSBench 사용

JSperf와 비교하여 JSBench ( https://jsbench.me/ )는 더 강력한 포괄적 인 성능을 제공합니다.

 Teardown : 마무리 작업을 수행합니다. 예를 들어 데이터베이스에 연결 한 후 데이터 작업을 완료하면 연결을 해제해야합니다. 일반적으로 js 코드가 실행 된 후 호출하는 함수 작업은 동일 할 수 있으며 사용 사례에서 작성할 필요가 없으므로 추출하여 Teardown에 넣는 것으로 충분합니다.

테스트 할 때 하나의 탭만 열어보십시오.

둘째, 스택의 JS 실행 프로세스

let a  = 10;
function foo(b){
    let a = 2
    function baz(c){
        console.log(a+b+c)
    }
    return baz
}
let fn = foo(2)
fn(3)

js 코드가 실행되기 시작하면 먼저 힙 메모리에 실행 환경 스택을 만든 다음이를 사용하여 다른 실행 컨텍스트를 저장합니다. 코드는 위에서 아래로 실행됩니다. 가장 먼저 생성하는 것은 ECG (글로벌 컨텍스트) 여야합니다. 여기에서 글로벌 범위 아래에 일부 코드를 선언하고 저장 한 다음 기본 데이터 유형 값이 있습니다. 메모리 및 참조 유형의 경우 일반적으로 GC에서 재활용하는 힙 영역에 저장되며 스택 영역의 항목은 현재 js 마스터 스레드가 스택에서 가져와야합니다. 함수 실행이 발생할 때마다 실행 컨텍스트를 다시 생성 한 다음 스택으로 푸시합니다. 코드가 실행 된 후 클로저 생성 여부는 현재 컨텍스트에서 참조 된 힙을 해제해야하는지 여부를 결정합니다.

셋째, 판단 수준을 낮추십시오.

 

function doSomething(part,chapter){
    const parts = ['ES2016','工程化','Vue','React','Node']
    if(part){
        if(parts.includes(part)){
            console.log('属于当前课程')
            if(chapter >5){
                console.log('您需要提供 VIP 身份')
            }
        }
    } else {
        console.log('请确认模块信息')
    }
}

// doSomething('ES2016',6)

function doSomething(part,chapter){
    const parts = ['ES2016','工程化','Vue','React','Node']
    if(!part){
        console.log('请确认模块信息')
        return
    }
    if (!parts.includes(part)) return
    if(chapter > 5){
        console.log('您需要提供 VIP 身份')
    }
}
doSomething('ES2016',6)

 넷째, 범위 체인 조회 수준을 줄입니다.

// var name = 'zce'

// function foo(){
//     name = 'zce666' //这里的Name是属于全局的
//     function baz(){
//         var age = 38
//         console.log(age)
//         console.log(name)
//     }
//     baz()
// }

// foo()

var name = 'zce'

function foo(){
    var name = 'zce666' //这里的Name是属于全局的,当前面加var时,此时的name就不用了再往外查找了
    function baz(){
        var age = 38
        console.log(age)
        console.log(name)
    }
    baz()
}

foo()

 다섯, 데이터 읽기 수를 줄입니다.

<!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>
    <div id="skip" class="skip"></div>
<script type="text/javascript">
    var oBox = document.getElementById('skip')
    // function hasEle(ele,cls){
    /*若是按照ele.className这样写的话,相当于每次使用数据的时候都要去查询一下,如果这个查询的属性在我们当前对象里面又进行了嵌套,
    层级非常的深,这时候所消耗的时间就非常的多,所以考虑把ele.className缓存起来*/
    //     return ele.className === cls 
    // }

    function hasEle(ele,cls){
        var clsname = ele.className//只需读取一次缓存起来
        return clsname === cls
    }
    console.log(hasEle(oBox,'skip'))
</script> 
</body> 
</html>

이런 종류의 속도는 여전히 공간 소비를 전제로하고 있으며 기준 형이라면 상대적으로 큰 공간입니다. 여러 번 읽어야하는 경우 가능한 한 많이 캐시하십시오.

여섯, 문자적인 양과 건설적인 공식

let test = () =>{// 把创建对象步骤放到函数里面,用new关键字构造函数的方式来创建obj
    let obj = new Object()
    obj.name = 'zce'
    obj.age = 38
    obj.slogan = '我爱你'
    return obj
}//做这个操作的时候好比调用一个函数,涉及到了函数的调用,所以它事情就做的更多一些,时间就消耗的多一些,扩容的时候这种方法更好一些

let test = () =>{
    let obj = {
        name:'zce',
        age:38,
        slogan:'我为前端而活'
    }
    return obj
}//而这个就相当于开辟一个空间往里面存东西就行了
console.log(test())
//==============================================================================================================
var str1 = 'zce说我为前端而活'
var str2 = new String('zce说我为前端而活')/*这是一个对象,它的好处是可以直接沿着原型链调用方法,但是上面的那个不能够调用,对于我们还是少占用空间,
这样子创建的话肯定要有多余的空间来存放obj上的属性或者方法*/

str1.slice //这样操作时会默认先把str1转成str2这种对象,然后再调用方法,即使不转也是属于我们当前对象下的一个实例,按照原型链也能找到
console.log(str1)
console.log(str2)

일곱, 순환계의 활동을 줄입니다

// var test = () =>{
//     var i
//     var arr = ['zce',38,'我为前端而活']
//     for(i = 0;i<arr.length;i++){
//         console.log(arr[i])
//     }
// }

// var test = () =>{
//     var i
//     var arr = ['zce',38,'我为前端而活']
//     var len = arr.length
//     for(i = 0;i<len;i++){//尽可能的减少循环体里面的操作
//         console.log(arr[i])
//     }
// }

var test = () =>{
    var arr = ['zce',38,'我为前端而活']
    var len = arr.length
    while(len --){//从后往前找,当小于0时就不成立了
        console.log(arr[len]) 
    }
}
test()

 

 8. 진술 및 진술의 수를 줄입니다.

<!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>
    <div id="box" style="width: 100px;height: 100px;"></div>
<script type="text/javascript">
// var oBox = document.getElementById('box')

// var test = (ele) => {
//     let w = ele.offsetWidth
//     let h = ele.offsetHeight
//     return w * h
// }

// var test = (ele) => {
//     return ele.offsetWidth * ele.offsetHeight
// }
// console.log(text(oBox))

var test = () => {// 更倾向于这样写,代码结构清晰一些,有利于维护
    var name = 'zce'
    var age = 38
    var slogan = '我为前端而活'
    return name + age + slogan
}

var test = () => {
    var name = 'zce',
         age = 38,
        slogan = '我为前端而活'
    return name + age + slogan
}
console.log(test())
</script> 
</body> 
</html>

9 개의 게으른 기능 및 성능

<!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">
        点击
    </button>
<script type="text/javascript">
    var oBtn = document.getElementById('btn')

    function foo(){
        console.log(this)
    }
    // function addEvent(obj,type,fn){
    //     if(obj.addEventListener){
    //         obj.addEventListener(type,fn,false)
    //     }else if(obj.attachEvent) {
    //         obj.attachEvent('on' + type,fn)
    //     } else {
    //         obj['on' + type] = fn
    //     }
    // }

    function addEvent(obj,type,fn){
        if(obj.addEventListener){
            addEvent = obj.addEventListener(type,fn,false)
        }else if(obj.attachEvent) {
            addEvent = obj.attachEvent('on' + type,fn)
        } else {
            addEvent = obj['on' + type] = fn
        }
        return addEvent
    }

    addEvent(oBtn,'click',foo)
</script> 
</body> 
</html>

현재 시나리오에 따르면 실제로 다음 쓰기 방법의 실행 속도가 느리다는 것을 알 수 있습니다. 이 접근 방식은 실제로 addEvent 값에 대한 재 할당 작업을 수행하는 것입니다. 조건이 충족되면 두 번째로 들어올 때를 판단 할 필요가 없지만 들어 와서 마지막 성공 값으로 호출 할 수 있습니다. 특히, 우리가 선택하는 방법은 위의 코드의 명확하고 직관적 인 유형을 원하는지 또는 다음을 원하는지에 따라 다릅니다.

10. 이벤트 위임 채택

<!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>
    <ul id="ul">
        <li>zce</li>
        <li>28</li>
        <li>我为前端而活</li>
    </ul>
<script type="text/javascript">
    var list = document.querySelectorAll('li')
    // function showTxt(ev){
    //     console.log(ev.target.innerHTML)
    // }
    // for(let item of list){
    //     item.onclick = showTxt
    // }

    var oUl = document.getElementById('ul')
    oUl.addEventListener('click',showTxt,true)
    function showTxt(ev){
        var obj = ev.target
        if(obj.nodeName.toLowerCae() === 'li'){
            console.log(obj.innerHTML)
        }
    }
</script> 
</body> 
</html>

 

추천

출처blog.csdn.net/weixin_41962912/article/details/110239068