ITPub博客

首页 > 应用开发 > > 让 JavaScript 变快的几个小技巧

让 JavaScript 变快的几个小技巧

作者:welchang 时间:2019-10-28 15:26:34 0 删除 编辑

前端下午茶 



大部分前端工程师入门的理由是:前端好上手,在最初学习的时候,甚至不需要 IDE 就可以开始 coding 了。但随着对语言的深入,也会慢慢了解到为什么做前端经常被后端“鄙视”,更深一层次的是,为什么 JavaScript 这门语言常常也会被鄙视。

JavaScript 从设计之初,就是很随性的:随性的作用域、随性的变量声明....虽然随着语言不断的升级,很多问题都可以用新的语法和特性规避了,但是实际开发起来,由于开发者的自我约束低甚至是不自知,写出来的代码还是会出现一些性能问题的——一不小心,就会让 JavaScript 变慢。

接下来我会分享一些实际开发中的小技巧,目的是让 JavaScript 跑得更快~

善用局部变量

当一个变量被引用时,JavaScript 会沿着作用域链逐级向下查找它。在这个作用域链中,通常都会包含一些可访问的局部变量,还有一些几乎所有主流浏览器都实现了的全局变量。JavaScript 引擎会首先查找挂载到当前作用域下和以函数参数形式传递进来的局部变量,然后是定义在函数作用域/块级作用域内的局部变量,最后去遍历查找全局变量。简而言之,需要访问变量所在的作用域链越深,代码执行时的耗时就越长。

局部变量总是第一个被查找的,也就是说,局部变量总是最快被查找到的,因此,当你需要多次使用一个全局变量时,最直接的优化方式就是将它定义成为局部变量,like this:

// 优化前

const div = document.querySelector('#div')

const images = document.querySelectorAll('img')

// 优化后

const doc = document

const div = doc.querySelector('#div')

const images = doc.querySelectorAll('img');

打死也别用 with()

众所周知,with() 语句是个魔鬼。这是因为它会把一坨额外的变量挂到作为参数的作用域上,这意味着每当任何一个变量被使用到时,JavaScript 引擎首先会将 with() 中的作用域遍历一遍,然后才是各个局部变量及全局变量,也就是说,有了它的存在,引擎查找变量的路劲就会不可避免的变长,进而降低了 JavaScript 执行时的性能。

玩归玩闹归闹,别拿闭包开玩笑

闭包是 JavaScript 中很实用的一个特性,但它是一把双刃剑,自打出生起就有着性能上的缺陷。

大部分时候你可能没察觉自己用到了闭包,但实际上,你确实已经写了不少了,比如:

document.querySelector('#div').onclick = function(ev) {

console.log('Hello Closure');

}

在定义一个闭包时,它的问题就出现了,闭包会使得函数中的变量都保存在内存中,对内存造成很大的消耗。即便如此,闭包仍是一个很有用的语言特性,在多数场景下能为开发者提供便利并且提高代码的可读性,所以,闭包虽好,可不要贪杯哦。

普通变量的存取是最快的

当谈及 JavaScript 数据时,最常见的有四种表达形式:字面量、变量、对象属性和数组项。如果从性能层面考量,字面量和变量相差无几,但都明显快过对象属性和数组项。

所以,当你需要多次读取/赋值同一个对象属性或数组项时,可以通过定义普通变量来提高代码的性能。

虽然 Firefox 搞了一些事情,让数组的存取效率超过了普通变量,但如果你的用户们并不完全是 Firefox 的忠实粉丝,还是乖乖的遵循这条规则吧。

保持数组的扁平化

在日常开发中,尤其是和后端同学定数据协议时,要尽量避免多维数组的出现。道理也很简单,层级越深,操作越慢。简而言之,数组的读取本身就不是一件很快的事情,再搞个多维数组那可就更慢了。

请彻底抛弃 for-in 循环

都 9102 年了,遍历一个对象的时候还在用 for-in?for-in 会遍历指定对象及其原型链上的所有可枚举属性,也就是说,由于总是干一些多余的事情,会导致这行遍历代码慢下来,就算用 hasOwnProperty 得出了预期的结果,但...它还是会去遍历那些继承来的属性呀(摊手)

于是乎,我建议采用这样的写法(我平时就是这么干的):

const keys = Object.keys(obj);

for (const key of keys) {

console.log(obj[key]);

}

Object.keys() 天生就是用来遍历一个对象自身的所有可枚举属性,并且以数组的形式返回,这样就不用担心遍历的时候做了一些拖慢性能的无用功了。

一时间也想不到其他的了,如果你有一些别的技巧可以分享,不妨贴在评论区,一起学习进步喔

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4830/viewspace-3153686/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-07-17

  • 博文量
    252
  • 访问量
    17990