Home >Web Front-end >JS Tutorial >Summary and sharing of 10 JavaScript code optimization tips

Summary and sharing of 10 JavaScript code optimization tips

WBOY
WBOYforward
2022-08-01 15:00:381611browse

This article brings you relevant knowledge about javascript. It mainly introduces the summary and sharing of 10 JavaScript code optimization tips. The article provides a detailed introduction around the theme, which has certain reference value. ,I hope everyone has to help.

Summary and sharing of 10 JavaScript code optimization tips

[Related recommendations: javascript video tutorial, web front-end

Write in front

To achieve JavaScript code optimization, the first thing you need to do is to accurately test the JavaScript code execution time. In fact, what needs to be done is to collect a large number of execution samples for mathematical statistics and analysis. Here we use benchmark.js to detect the execution of the code.

First we need to install dependencies in the project, the code is as follows:

yarn add benchmark --save
# 或者
npm i benchmark --save

Then we write a test code as follows:

const Benchmark = require('benchmark')
const suite = new Benchmark.Suite()
// 添加测试
suite
  /**
   * add() 方法接受两个参数,其中第一个表示测试的名称,第二个表示测试的内容,他是一个函数*   
/
  .add('join1000', () => {
    new Array(1000).join(' ')
  })
  .add('join10000', () => {
    new Array(10000).join(' ')
  })
  // 添加时间监听
  .on('cycle', event => {
    // 打印执行时间
    console.log(String(event.target))
  })
  // 完成后执行触发的事件
  .on('complete', () => {
    console.log('最快的是:' + suite.filter('fastest').map('name'))
  })
  // 执行测试
  .run({ async: true })

复制代码

The code execution results are as follows:

// join1000 x 146,854 ops/sec ±1.86% (88 runs sampled)
// join10000 x 16,083 ops /sec ±1.06% (92 runs sampled)
// The fastest is: join1000

In the results, ops/sec represents execution per second The number of times, of course, the bigger the better, followed by the percentage difference between the upper and lower execution times per second, and finally the content in parentheses indicates the total number of sampling times. We can see that the performance of join1000 is better (I feel like I am talking nonsense).

Use global variables with caution

The global variables mentioned here should be used with caution. Why should they be used with caution? The main points are as follows:

  • Global variables are defined in the global execution context and are the top of all scope chains. Every time you search, you will find the top part from the top, which will consume some time.
  • The global execution context always exists in the execution stack of the context and will not be destroyed until the program exits, which is a waste of memory space.
  • If a variable with the same name appears in a local scope, it will cover or pollute the global variable.

Let’s write a piece of code to see the difference in execution efficiency between global variables and layout variables. The code is as follows:

...
suite
  .add('全局变量', () => {
    // 该函数内模拟全局作用域
    let i,
      str = ''
    for (i = 0; i < 1000; i++) {
      str += i
    }
  })
  .add(&#39;局部变量&#39;, () => {
    for (let i = 0, str = &#39;&#39;; i < 1000; i++) {
      str += i
    }
  })
...

The code running results are as follows:

Global variables x 158,697 ops/sec ±1.05% (87 runs sampled)

Local variables x 160,697 ops/sec ±1.03% (90 runs sampled)
The fastest is: local variables

Although the difference is not big, we can perceive that the performance of global variables is worse than that of local variables.

Add methods through prototype

When adding methods required by instance objects to the constructor, try to add them using the prototype instead of adding them inside the constructor. We can see the following test code:

...
suite
  .add(&#39;构造函数内部添加&#39;, () => {
    function Person() {
      this.sayMe = function () {
        return &#39;一碗周&#39;
      }
    }
    let p = new Person()
  })
  .add(&#39;原型方式内部添加&#39;, () => {
    function Person() {}
    Person.prototype.sayMe = function () {
      return &#39;一碗周&#39;
    }
    let p = new Person()
  })
...

The code running results are as follows:

Add x 573,786 ops/sec ±1.97% (89 runs sampled) inside the constructor

Inside the prototype method Added Packages will cause the variables in the function to be stored in memory, which consumes a lot of memory, so closures cannot be abused, otherwise it will cause performance problems on the web page, and may seriously lead to memory leaks. The solution is to delete all unused local variables before exiting the function (that is, reassign the local variables to
null
).

Avoid using property access methods

In objects in JavaScript, avoid using some property access methods. This is because all properties in JavaScript are externally visible.

The sample code is as follows:

...
suite
  .add(&#39;使用属性访问方法&#39;, () => {
    function Person() {
      this.name = &#39;一碗周&#39;
      this.getName = function () {
        return &#39;一碗周&#39;
      }
    }
    let p = new Person()
    let n = p.getName()
  })
  .add(&#39;不使用属性访问方法&#39;, () => {
    function Person() {
      this.name = &#39;一碗周&#39;
    }
    let p = new Person()
    let n = p.name
  })
...

The code running result is as follows:

Use attribute access method x 406,682 ops /sec ±2.33% (82 runs sampled)

Does not use attribute access methods x 554,169 ops/sec ±2.03% (85 runs sampled)

Fastest is: does not use attribute access methods

for loop optimization

When we use the for loop, we can cache some necessary data, such as
arr.length
, which does not need to be obtained every time it is judged. to optimize our code.

The sample code is as follows:

...
suite
  .add(&#39;正序&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    for (let i = 0; i < arr.length; i++) {
      str += i
    }
  })
  .add(&#39;缓存&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    for (let i = arr.length; i; i--) {
      str += i
    }
  })
  .add(&#39;缓存的另一种写法&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    for (let i = 0, l = arr.length; i < l; i++) {
      str += i
    }
  })
...
The code running result is as follows:

Forward sequence x 1,322,889 ops/sec ±1.36% (86 runs sampled)

Cache x 1,356,696 ops/sec ±0.70% (92 runs sampled)

Another way of writing cache x 1,383,091 ops/sec ±0.70% (93 runs sampled) The fastest is: another way of writing cache

Choose the optimal loop method


The loops we commonly use now include
forEach
,

for
and

for...in

loops, which one has the best performance? The test code is as follows:

...
suite
  .add(&#39;forEach&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    arr.forEach(i => {
      str += i
    })
  })
  .add(&#39;for...in&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    for (i in arr) {
      str += i
    }
  })
  .add(&#39;for&#39;, () => {
    let arr = new Array(100)
    let str = &#39;&#39;
    for (let i = 0, l = arr.length; i < l; i++) {
      str += i
    }
  })
...
The code running results are as follows:

forEach x 4,248,577 ops/sec ±0.89% (86 runs sampled)
for...in x 4,583,375 ops/sec ±1.15% (91 runs sampled)
for x 1,343,871 ops/sec ±1.91% (88 runs sampled)
最快的是:for...in

由运行结果可以看出我们可以尽量使用for...in或者forEach循环,减少使用for循环。

减少判断层级

减少判断层级就是减少一些if语句的嵌套,如果是一些必要的条件我们可以通过单层if结合return直接跳出函数的执行,关于优化前与优化后的代码执行比对如下所示:

...
/*** 
 接收两类文件,zip 和 rar* 
 压缩包的大小限制为 10 兆* 
/

suite
  .add(&#39;嵌套写法&#39;, () => {
    function uploadFile(suffix, size) {
      // 允许上传的后缀名
      const suffixList = [&#39;.zip&#39;, &#39;.rar&#39;]
      const M = 1024*  1024

      if (suffixList.includes(suffix)) {
        if (size <= 10*  M) {
          return &#39;下载成功&#39;
        }
      }
    }
    uploadFile(&#39;.zip&#39;, 1*  1024*  1024)
  })
  .add(&#39;减少判断写法&#39;, () => {
    function uploadFile(suffix, size) {
      // 允许上传的后缀名
      const suffixList = [&#39;.zip&#39;, &#39;.rar&#39;]
      const M = 1024*  1024
      if (!suffixList.includes(suffix)) return
      if (size > 10*  M) return
      return &#39;下载成功&#39;
    }
    uploadFile(&#39;.zip&#39;, 1*  1024*  1024)
  })
...

代码运行结果如下:

嵌套写法 x 888,445,014 ops/sec ±2.48% (88 runs sampled)
减少判断写法 x 905,763,884 ops/sec ±1.35% (92 runs sampled)
最快的是:减少判断写法,嵌套写法

虽然说差距并不是很大,但是不适用嵌套的代码比普通代码更优一些。

减少作用域链查找层级

减少代码中作用域链的查找也是代码优化的一种方法,如下代码展示了两者的区别:

...
suite
  .add(&#39;before&#39;, () => {
    var name = &#39;一碗粥&#39;
    function sayMe() {
      name = &#39;一碗周&#39;
      function print() {
        var age = 18
        return name + age
      }
      print()
    }
    sayMe()
  })
  .add(&#39;after&#39;, () => {
    var name = &#39;一碗粥&#39;
    function sayMe() {
      var name = &#39;一碗周&#39; // 形成局部作用域
      function print() {
        var age = 18
        return name + age
      }
      print()
    }
    sayMe()
  })
...

代码运行结果如下:

before x 15,509,793 ops/sec ±7.78% (76 runs sampled)
after x 17,930,066 ops/sec ±2.89% (83 runs sampled)
最快的是:after

上面代码只是为了展示区别,并没有实际意义。

减少数据读取次数

如果对象中的某个数据在一个代码块中使用两遍以上,这样的话将其进行缓存从而减少数据的读取次数来达到更优的一个性能,

测试代码如下:

...
var userList = {
  one: {
    name: &#39;一碗周&#39;,
    age: 18,
  },
  two: {
    name: &#39;一碗粥&#39;,
    age: 18,
  },
}
suite
  .add(&#39;before&#39;, () => {
    function returnOneInfo() {
      userList.one.info = userList.one.name + userList.one.age
    }
    returnOneInfo()
  })
  .add(&#39;after&#39;, () => {
    function returnOneInfo() {
      let one = userList.one
      one.info = one.name + one.age
    }
    returnOneInfo()
  })
...

代码运行结果如下:

before x 222,553,199 ops/sec ±16.63% (26 runs sampled)
after x 177,894,903 ops/sec ±1.85% (88 runs sampled)
最快的是:before

字面量与构造式

凡是可以使用字面量方式声明的内容,绝对是不可以使用构造函数的方式声明的,两者在性能方面相差甚远,代码如下:

...
suite
  .add(&#39;before&#39;, () => {
    var str = new String(&#39;string&#39;)
  })
  .add(&#39;after&#39;, () => {
    var str = &#39;string&#39;
  })
...

代码运行结果如下:

before x 38,601,223 ops/sec ±1.16% (89 runs sampled)
after x 897,491,903 ops/sec ±0.92% (92 runs sampled)
最快的是:after

【相关推荐:javascript视频教程web前端

The above is the detailed content of Summary and sharing of 10 JavaScript code optimization tips. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jb51.net. If there is any infringement, please contact admin@php.cn delete