前端js代码优化

js是单线程机制的解释型语言,在必要的时候优化代码的形式可以加快程序的运行

jsbench

jsbench是一个前端代码速度测试网站,可以比较多段代码的运行效率:https://jsbench.me/

优化方式

慎用全局变量

  • 全局变量位于全局作用域,在局部作用域中需要逐层向上查找
  • 全局变量在全局执行上下文中,会一直存在于作用域栈,直到程序结束才能被GC算法回收
  • 局部执行上下文中出现同名变量,则会污染全局变量
    jsbench中比较两段代码

缓存全局变量

如果某些全局变量的查找无法避免,那就尝试在局部作用域中缓存它,然后利用缓存的数据进行操作
选取两段代码对dom进行操作,在jsbench中测试如下:
在这里插入图片描述

在原型对象上添加附加方法

实例需要使用的方法可以定义在原型对象上而不是构造函数内部
因为构造函数内部声明的方法每次创建实例的时候都需要在内存中创建这个方法,在这里插入图片描述

避开闭包陷阱

由于闭包存在,外部可以对内部作用域的变量进行引用,导致内部作用域无法被释放,造成内存泄漏
内部作用域中不需要的引用要释放掉

<body>
    <button id="btn" class="btn">click</button>
    <script>
        function click(){
            let btn = document.getElementById("btn")
            btn.onclick = function(){
                console.log(btn)
            }
        }
        click()
    </script>
</body>

修改为:

<body>
    <button id="btn" class="btn">click</button>
    <script>
        function click(){
            let btn = document.getElementById("btn")
            btn.onclick = function(){
                console.log(btn)
               
            }
             btn = null
        }
        click()
    </script>
</body>

for循环优化

使用for循环可以用字面量替代对属性的多次访问
比较两段for循环区别如下
在这里插入图片描述

几种循环的时间花销比较

foreach最快,forin最慢
在这里插入图片描述

文档碎片优化节点添加

对文档的添加删除会产生回流和重绘,影响页面效率,应该减少对整个文档流的影响

 //before
        for(let i = 0;i<5;++i){
            let span = document.createElement("span")
            span.innerHTML = i
            document.body.appendChild(span)
        }
        //after
        let fag = document.createDocumentFragment()
        for(let i = 0;i<5;++i){
            let span = document.createElement("span")
            span.innerHTML = i;
            fag.appendChild(span)
        }
        document.body.appendChild(fag)

克隆优化节点

如果页面已有类似节点,可以考虑以克隆的方式代替再次创建

 <span id="sp">sx</span>
    <script>
        //before
        for(let i = 0;i<5;++i){
            let span = document.createElement("span")
            span.innerHTML = i
            document.body.appendChild(span)
        }
        //after
        let sp = document.getElementById("sp")
        console.log(sp)
        for (let index = 0; index < 5; index++) {
            let span = sp.cloneNode(false) 
            span.innerHTML = index
            document.body.appendChild(span)         
        }
    </script>

直接量替换new object操作

//before 
let arr = new Array()
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;

//after

let arr = [1,2,3]

减少层级判断

通过条件提前return 不符合的流程,达到减少条件判断层级嵌套的问题

//判断是否是18岁的小明
//before

function judgeMing(name,age){
    if(name==='小明'){
        if(age === 18){
            console.log('正确')
        }
        else {
            console.log('错误')
        }
    }
    else {
        console.log('错误')
    }
}

//after

function judgeMing(name,age){
    if(name!=="小明"|| age!==18)
        console.log('错误')
    else {
        console.log('正确')
    }
}

减少作用域链查找层级

原理和慎用全局变量类似,值得一提的是,为了加快运行效率,会利用局部变量将外部作用域的值缓存,或者重新定义一个值,会加大内存的开销

//before

let name = 'sx'
function foo(){
    let getName = ()=>{
        console.log(name)
    }
}

//after

let name = 'sx'
function foo(){
    let name = 'sx2'
    let getName = ()=>{
        console.log(name)
    }
}

采用事件绑定

 <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>

    </ul>
    <script>
        function show(){
            console.log('sx')
        }
        //before 
        let item = document.getElementsByTagName("li")
        for(let i of item){
            i.onclick = show
        }

        //after
        let ul = document.getElementsByTagName("ul")
        ul[0].addEventListener('click',show,true)
    </script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问也去

创作不易,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值