高性能javascript编码注意事项,读《高性能javascript》简单总结

《高性能javascript》不是一本很厚的书,草草10章,从编码的tips,UI线程,ajax请求到应用部署和工具使用,从多个方面罗列了js不同情况下的性能表现和比较。但结合目前前端技术的趋势,直接动手用js,html,css直接硬撸的写法越来越少了,当然一些祖传代码除外。取而代之的是各种前端框架,例如vue,react,angular,uniapp,flutter等。这就使得那些自甘堕落的程序员(我也是其中之一),不求甚解,很少直接使用js去操控DOM元素,或硬撸一套ajax的接口。

 

万变不离其宗。框架再完善,很多js的代码还是需要自己手敲。所以了解并记住一些js编程中的注意事项,总是有或多或少的帮助。

下面介绍一下在常用的编码场景中,高性能代码的写法(总结自书中,不接受引战)。

(一)数据存储

在js中数据存储会对代码的性能有重要的影响。数据存储有4中方法:字面量,变量,数组项,对象成员,他们有着各自的性能特点。

1、字面量和局部变量的访问速度是最快的,相反访问数组元素、全局变量、对象成员则相对较慢

2、局部变量存在于作用域链的最开始位置,局部变量性能远好于全局变量,尤其是跨作用域的访问(可以简单的理解为跨文件的引用这种)

3、避免使用with语句和try,catch中的catch,它们会改变执行环境作用域链

4、嵌套的对象成员会明显印象性能,尽量少用。

5、所有的对象成员,数组,跨域变量在使用的时候,最佳方式是使用局部变量赋值之后使用。

例如经常使用object.b这个成员,需要定义局部变量var tmp = object.b

 

(二)算法和流程控制

1、基于函数的迭代foreach,each,性能要差于简单的for,while,do-while等循环,只有他们的1/8,尽量少用基于函数的迭代,还包括every。

2、不要使用for in,除非在一个属性数量未知的对象,它的效率只有普通循环的1/7;

3、在for语句中的判断条件,将每次都要取的length改为使用局部变量,大部分浏览器中可以提升25%的性能

低效写法:for(var i=0, i<items.length, i++)
高效写法:var len = items.length
          for(var i=0, i<len, i++)

4、使用倒序的写法,并将true和false的比较改为直接与0比较,0在bool时直接就是false。上面第3点中的传统写法,会先计算出i<len的值是true还是false,再将结果与true比较。而直接用0来比较会减少一次计算取值(0就是false),在迭代次数很多的时候会提高50%左右的性能

for(var i = items.length, i--,){
    process()
}

var j = items.length
while(j--) {
    process()
}

5、使用“达夫设备”,代替传统的循环。正常的写法一个长度1000的数组process函数调用1000次,且i--,i<len的比较同样进行1000次。而达夫设备的写法是循环1次,一次连着运行8次process,当迭代次数很多时候,例如50000次的时候,性能可以提高70%。  这么看达夫设备就是为了减少比较次数,节省性能

// 处理余数
var i = items.length % 8
while(i) {
    process(item[i--]
}

// 处理整除数的主循环
j = Math.floor(length/8)

while(j){
    process(item[i--])
    process(item[i--])
    process(item[i--])
    process(item[i--])
    process(item[i--])
    process(item[i--])
    process(item[i--])
    process(item[i--])
}

6、if else和switch。在条件众多的时候倾向于用switch,条件很少的时候使用if else。当if else的离散值有多个的时候,尽量的写法是要比较每个值都进行比较,高性能的写法是:

if (value < 6) {
    if(val < 3) {
        if(val === 0){}
        else if(val === 1){}
        else{// 这里就是等于2的时候}
    } else {
        if(val === 3){}
        else if(val === 4){}
        else{// 这里就是等于5的时候}
    }
}

上述写法就是为了减少比较的次数,但遇到这种情况就直接用switch吧

7、如果离散的值还要更多,那么直接用数据的查找表来实现item[i],这样几乎不会产生额外的性能开销。

8、尽量比较减少迭代,反复的在一个函数中调用函数,比老老实实写一个循环开销要大的多,而且迭代函数的可读性也不如循环来的直观和简单。

以上的写法也许不会让你的代码运行速度马上提升飞快,但如果数据量巨大的时候应该还是有起飞般的提升。但是掌握一种可给给出明确正向理由的写法时,不正是给了我们这些在纠结最优写法的一个交代吗。

(三)字符串相关的优化写法

字符串是每个语言都离不开的变量类型,在js中更是使用非常的频繁,掌握它的相关高效写法,多多少少会提升代码性能。最不济当A和B两种写法都可以的时候,给了你一种较为正确选择的理由,拒绝纠结,快速决断。

1、字符串连接

如果这么写一个语句str += “one” + “two”,代码运行时会有多个步骤,创建两个临时变量,连接两个临时变量,然后和str连接,最后赋值给str变量。

更简便的写法是,分开使用自加运算符:

str += “one”

str += “two”

这样避免了使用临时变量和开辟内存空间,大多数浏览器中可以提升10% - 40%的性能。

2、数组项合并,使用array.join()

在目前大多数的浏览器中,这个方法都比+=更慢,但是由于这个函数真的很好用,所以如果有业务需求,数据量大的话,那么就直接用即可。毕竟少写几行代码和性能的权衡,我还是愿意少写代码吧(笑哭)

3、string.contact()字符串连接函数

这个函数性能也会比+,+=更慢,所以如果是数量少的字符串连接尽量使用+,+=符号。

字符串相关的性能写法,书上讲的不多,简单总结来看+,+=是性能最佳的写法,如果字符串数量少的话,就直接+,+=即可。

 

这本书简单就叙述那么多,后面章节的内容就是手撸UI、ajax的东西了,由于很少用到,就暂且略过。

2020-7-10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值