JavaScript performance optimization 2 (code optimization)

Article description: This article is the notes and experience of the front-end training camp of Regao. If there is something wrong, I hope you can point out and teach, thank you! 

One, JSBench use

Compared with JSperf, JSBench ( https://jsbench.me/ ) has stronger comprehensive performance.

 Teardown: Do a finishing touch. For example, after we connect to the database, if we have finished operating the data, we should release the connection. Normally, after our js code is executed, the function operations we call may be the same, and there is no need to write them in the use case, so it is enough to extract them and put them in Teardown.

Try to open only one tab when testing.

Second, the JS execution process in the stack

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)

After the js code starts to execute, it first creates an execution environment stack in the heap memory, and then we use it to store different execution contexts. The code is executed from top to bottom. The first thing we create should be ECG, which is the global context. Here, we declare and store some codes under the global scope, and then there is the basic data type value, which is directly stored in our stack. In the memory, and for reference types, they are stored in our heap area, which is usually recycled by our GC, and things in the stack area must be pulled out of the stack by the current js master Threads are managed. Whenever we encounter function execution, it will regenerate an execution context and then push it to the stack. After the code is executed, whether to generate a closure determines whether the heap referenced in our current context should be released.

Third, reduce the level of judgment

 

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)

 Fourth, reduce the scope chain lookup level

// 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()

 Five, reduce the number of data reads

<!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>

This kind of speed is still based on the premise of space consumption. If it is a reference type, it is a relatively large space. If you need to read multiple times, cache it as much as possible

Six, literal quantity and constructive formula

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)

Seven, reduce the activity in the circulatory body

// 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. Reduce the number of statements and statements

<!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>

Nine, lazy functions and performance

<!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>

Based on the current scenario, the result we see is indeed that the execution speed of the following writing method is slower. This approach is actually to do a reassignment operation to the value of addEvent. When our conditions are met, we don't need to judge the second time we come in, but we can just come in and call it with the last successful value. Specifically, how we choose depends on whether we want the clear and intuitive type of code above or the following.

10. Adopt event delegation

<!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>

 

Guess you like

Origin blog.csdn.net/weixin_41962912/article/details/110239068