资讯专栏INFORMATION COLUMN

前端性能优化JavaScript篇

chuyao / 1773人阅读

摘要:减少作用域链上的查找次数。尽量少用全局变量,尽量使用局部变量。全局变量如果不手动销毁,会一直存在,造成全局变量污染,可能很产生一些意想不到的错误,而局部变量运行完成后,就被会被回收使用代替大量的内联样式修改。性能优化还需要继续深入研究。

关于前端性能优化的讨论一直都很多,包罗的知识也很多,可以说性能优化只有更好,没有最好。前面我写了一篇关于css优化的总结文章,今天再从javascript方面聊一聊。

1.从资源加载方面来说,浏览器的加载顺序是按源码从上到下加载解析的,遇到link,script等资源都会阻塞页面渲染,所以我们会把script放在前面,我们还可以结合构建工具(webpack,gulp...)压缩js文件,抽离公共js、去掉空格、注释,尽可能地让js文件变小,防止脚本阻塞页面渲染。

2.在写代码的时候我们还要注意以下问题。

(1)减少作用域链上的查找次数。我们知道,js代码在执行的时候,如果需要访问一个变量或者一个函数的时候,它需要从当前执行环境的作用域链一级一级地向上查找,直到全局作用域。如果我们需要经常访问全局环境的变量对象的时候,我们每次都必须在当前作用域链上一级一级的遍历,这显然是比较耗时的。

function getTitle() {
    var h1 = document.getElementByTagName("h1");
    for(var i = 0, len = h1.length; i < len; i++) {
        h1[i].innerHTML = document.title + " 测试 " + i;
    }
}

上面这样写就非常耗时,我们可以优化一下:

function getTitle() {
    var doc = document;
    var h1 = doc.getElementByTagName("h1");
    for(var i = 0, len = h1.length; i < len; i++) {
        h1[i].innerHTML = doc.title + " 测试 " + i;
    }
}

通过创建一个指向document的局部变量,就可以通过限制一次全局查找来改进这个函数的性能。

(2)闭包导致的内存泄露。
闭包可以保证函数内的变量安全,可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会被自动清除。使用场合:设计私有的方法和变量。使用不当就会造成内存占用过高。我们需要手动销毁内存中的变量。

(3)尽量少用全局变量,尽量使用局部变量。全局变量如果不手动销毁,会一直存在,造成全局变量污染,可能很产生一些意想不到的错误,而局部变量运行完成后,就被会被回收;

(4)使用classname代替大量的内联样式修改。很多时候我们会在用户操作的时候,页面元素样式会进行相应的变化,这时候我们就可以把要变化的样式写成一个class,操作class变化,就能实现大量样式的变化。

(5)批量元素绑定事件,可以使用事件委托。事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如我们有100个li,每个li都要绑定click点击事件,就可以用事件委托。举一个例子:我们需要给所有的button绑定click事件

我们有可能会这样写

window.onload = function(){
            var Add = document.getElementById("add");
            var Remove = document.getElementById("remove");
            var Move = document.getElementById("move");
            var Select = document.getElementById("select");
            
            Add.onclick = function(){
                alert("添加");
            };
            Remove.onclick = function(){
                alert("删除");
            };
            Move.onclick = function(){
                alert("移动");
            };
            Select.onclick = function(){
                alert("选择");
            }
        }

用事件委托就可以这样写:

window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == "input"){
                    switch(target.id){
                        case "add" :
                            alert("添加");
                            break;
                        case "remove" :
                            alert("删除");
                            break;
                        case "move" :
                            alert("移动");
                            break;
                        case "select" :
                            alert("选择");
                            break;
                    }
                }
            }
            
        }

而且使用事件委托,还有一个好处就是,当你添加一个新的button,一样的会绑定上click事件,这就是委托事件的好处。上面这样的写法是原生js的写法,jquery可以这样写:

$("#box").on("click","input",function(event){
             var targetId = $(this).attr("id");
              switch(targetId){
                        case "add" :
                            alert("添加");
                            break;
                        case "remove" :
                            alert("删除");
                            break;
                        case "move" :
                            alert("移动");
                            break;
                        case "select" :
                            alert("选择");
                            break;
                    }             
})

这样写就简便得多。

(6)避免不必要的DOM操作,尽量使用 ID 选择器:ID选择器是最快的,避免一层层地去查找节点。

(7)类型转换:把数字转换成字符串使用number + "" 。
虽然看起来比较丑一点,但事实上这个效率是最高的,性能上来说:

("" + ) > String() > .toString() > new String()  

(8)对字符串进行循环操作,譬如替换、查找,应使用正则表达式。因为本身JavaScript的循环速度就比较慢,而正则表达式的操作是用C写成的语言的API,性能很好。

(9)对象查询使用[""]查询要比.items()更快。这和前面的减少对象查找的思路是一样的,调用.items()增加了一次查询和函数的调用。

(10)浮点数转换成整型使用Math.floor()或者Math.round()。parseInt()是用于将字符串转换成数字,Math是内部对象,所以Math.floor()其实并没有多少查询方法和调用的时间,速度是最快的。

关于js性能优化来说,涉及到很多方面,特别是现在又出现很多的前端框架,优化方法又各有不同。上面说的这些只是很浅显的东西,在开发中多注意一下就可以了,尽量精简自己的代码。性能优化还需要继续深入研究。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/117216.html

相关文章

  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • 王下邀月熊_Chevalier的前端每周清单系列文章索引

    摘要:感谢王下邀月熊分享的前端每周清单,为方便大家阅读,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清单系列,并以年月为单位进行分类,具体内容看这里前端每周清单年度总结与盘点。 感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具...

    2501207950 评论0 收藏0
  • 王下邀月熊_Chevalier的前端每周清单系列文章索引

    摘要:感谢王下邀月熊分享的前端每周清单,为方便大家阅读,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清单系列,并以年月为单位进行分类,具体内容看这里前端每周清单年度总结与盘点。 感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具...

    Markxu 评论0 收藏0
  • 前端优化 - 收藏集 - 掘金

    摘要:虽然有着各种各样的不同,但是相同的是,他们前端优化不完全指南前端掘金篇幅可能有点长,我想先聊一聊阅读的方式,我希望你阅读的时候,能够把我当作你的竞争对手,你的梦想是超越我。 如何提升页面渲染效率 - 前端 - 掘金Web页面的性能 我们每天都会浏览很多的Web页面,使用很多基于Web的应用。这些站点看起来既不一样,用途也都各有不同,有在线视频,Social Media,新闻,邮件客户端...

    VincentFF 评论0 收藏0
  • 前端性能优化JavaScript

    摘要:减少作用域链上的查找次数。尽量少用全局变量,尽量使用局部变量。全局变量如果不手动销毁,会一直存在,造成全局变量污染,可能很产生一些意想不到的错误,而局部变量运行完成后,就被会被回收使用代替大量的内联样式修改。性能优化还需要继续深入研究。 关于前端性能优化的讨论一直都很多,包罗的知识也很多,可以说性能优化只有更好,没有最好。前面我写了一篇关于css优化的总结文章,今天再从javascri...

    guqiu 评论0 收藏0

发表评论

0条评论

chuyao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<