欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips

 更新時(shí)間:2022年07月13日 17:13:43   作者:??一碗周???  
這篇文章主要介紹了總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

寫(xiě)在前面

想要做到JavaScript的代碼優(yōu)化,首先需要做的是準(zhǔn)確的測(cè)試JavaScript的代碼執(zhí)行時(shí)間。其實(shí)需要做的就是采集大量的執(zhí)行樣本進(jìn)行數(shù)學(xué)統(tǒng)計(jì)和分析,這里我們使用的是benchmark.js來(lái)檢測(cè)代碼的執(zhí)行情況。

首先我們需要在項(xiàng)目中安裝依賴,代碼如下:

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

然后我們寫(xiě)一個(gè)測(cè)試代碼,如下所示:

const Benchmark = require('benchmark')
const suite = new Benchmark.Suite()
// 添加測(cè)試
suite
  /**
   * add() 方法接受兩個(gè)參數(shù),其中第一個(gè)表示測(cè)試的名稱,第二個(gè)表示測(cè)試的內(nèi)容,他是一個(gè)函數(shù)*   
/
  .add('join1000', () => {
    new Array(1000).join(' ')
  })
  .add('join10000', () => {
    new Array(10000).join(' ')
  })
  // 添加時(shí)間監(jiān)聽(tīng)
  .on('cycle', event => {
    // 打印執(zhí)行時(shí)間
    console.log(String(event.target))
  })
  // 完成后執(zhí)行觸發(fā)的事件
  .on('complete', () => {
    console.log('最快的是:' + suite.filter('fastest').map('name'))
  })
  // 執(zhí)行測(cè)試
  .run({ async: true })

復(fù)制代碼

代碼執(zhí)行結(jié)果如下:

// join1000 x 146,854 ops/sec ±1.86% (88 runs sampled)
// join10000 x 16,083 ops/sec ±1.06% (92 runs sampled)
// 最快的是:join1000

在結(jié)果中,ops/sec表示的是每秒執(zhí)行的次數(shù),當(dāng)然是越大越好,緊接著是每秒執(zhí)行次數(shù)上下相差的百分比,最后括號(hào)中的內(nèi)容表示共取樣多少次。

或者也可以使用JSBench.me工具進(jìn)行替換,網(wǎng)站測(cè)試截圖如下:

我們可以看到,都是join1000的性能更好一些(我感覺(jué)我在說(shuō)廢話)。

慎用全局變量

這里所說(shuō)的慎用全局變量,為什么要慎用呢?主要有以下幾點(diǎn):

  • 全局變量定義在全局執(zhí)行上下文,是所有作用域鏈的頂端。每次查找的時(shí)候都從局部找到最頂端,在時(shí)間上會(huì)有所消耗。
  • 全局執(zhí)行上下文一直存在于上下文的執(zhí)行棧,直到程序退出,才會(huì)被銷毀,內(nèi)存空間浪費(fèi) 。
  • 如果某個(gè)局部作用域出現(xiàn)了同名的變量則會(huì)遮蓋或者說(shuō)污染全局變量 。

下面我們就來(lái)寫(xiě)一段代碼,看一下全局變量與布局變量在執(zhí)行效率方面的差異,代碼如下:

...
suite
  .add('全局變量', () => {
    // 該函數(shù)內(nèi)模擬全局作用域
    let i,
      str = ''
    for (i = 0; i < 1000; i++) {
      str += i
    }
  })
  .add('局部變量', () => {
    for (let i = 0, str = ''; i < 1000; i++) {
      str += i
    }
  })
...

代碼運(yùn)行結(jié)果如下:

全局變量 x 158,697 ops/sec ±1.05% (87 runs sampled)
局部變量 x 160,697 ops/sec ±1.03% (90 runs sampled)
最快的是:局部變量

雖然說(shuō)差異不大,但是我們可以感知全局變量比局部的性能更差一些。

通過(guò)原型新增方法

為構(gòu)造函數(shù)增加實(shí)例對(duì)象需要的方法時(shí),盡量使用原型的方式添加,而不是構(gòu)造函數(shù)內(nèi)部進(jìn)行添加,我們可以看如下測(cè)試代碼:

...
suite
  .add('構(gòu)造函數(shù)內(nèi)部添加', () => {
    function Person() {
      this.sayMe = function () {
        return '一碗周'
      }
    }
    let p = new Person()
  })
  .add('原型方式內(nèi)部添加', () => {
    function Person() {}
    Person.prototype.sayMe = function () {
      return '一碗周'
    }
    let p = new Person()
  })
...

代碼運(yùn)行結(jié)果如下:

構(gòu)造函數(shù)內(nèi)部添加 x 573,786 ops/sec ±1.97% (89 runs sampled)
原型方式內(nèi)部添加 x 581,693 ops/sec ±3.46% (80 runs sampled)
最快的是:構(gòu)造函數(shù)內(nèi)部添加

避免閉包中的內(nèi)存泄露

由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,嚴(yán)重可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除 (即將局部變量重新賦值為null)。

避免使用屬性訪問(wèn)方法

在JavaScript中的對(duì)象中,避免使用一些屬性訪問(wèn)方法,這是因?yàn)镴avaScript中的所有屬性都是外部可見(jiàn)的。

示例代碼如下:

...
suite
  .add('使用屬性訪問(wèn)方法', () => {
    function Person() {
      this.name = '一碗周'
      this.getName = function () {
        return '一碗周'
      }
    }
    let p = new Person()
    let n = p.getName()
  })
  .add('不使用屬性訪問(wèn)方法', () => {
    function Person() {
      this.name = '一碗周'
    }
    let p = new Person()
    let n = p.name
  })
...

代碼運(yùn)行結(jié)果如下:

使用屬性訪問(wèn)方法 x 406,682 ops/sec ±2.33% (82 runs sampled)
不使用屬性訪問(wèn)方法 x 554,169 ops/sec ±2.03% (85 runs sampled)
最快的是:不使用屬性訪問(wèn)方法

for循環(huán)優(yōu)化

我們?cè)谑褂胒or循環(huán)時(shí),可以將有些必要的數(shù)據(jù)進(jìn)行緩存,就比如arr.length這種屬性,不需要每次判斷都獲取一下,從而優(yōu)化我們的代碼。

示例代碼如下:

...
suite
  .add('正序', () => {
    let arr = new Array(100)
    let str = ''
    for (let i = 0; i < arr.length; i++) {
      str += i
    }
  })
  .add('緩存', () => {
    let arr = new Array(100)
    let str = ''
    for (let i = arr.length; i; i--) {
      str += i
    }
  })
  .add('緩存的另一種寫(xiě)法', () => {
    let arr = new Array(100)
    let str = ''
    for (let i = 0, l = arr.length; i < l; i++) {
      str += i
    }
  })
...

代碼運(yùn)行結(jié)果如下:

正序 x 1,322,889 ops/sec ±1.36% (86 runs sampled)
緩存 x 1,356,696 ops/sec ±0.70% (92 runs sampled)
緩存的另一種寫(xiě)法 x 1,383,091 ops/sec ±0.70% (93 runs sampled)
最快的是:緩存的另一種寫(xiě)法

選擇最優(yōu)的循環(huán)方式

我們現(xiàn)在常用的循環(huán)有forEach、forfor...in循環(huán),這幾種那個(gè)是性能最優(yōu)的呢,測(cè)試代碼如下:

...
suite
  .add('forEach', () => {
    let arr = new Array(100)
    let str = ''
    arr.forEach(i => {
      str += i
    })
  })
  .add('for...in', () => {
    let arr = new Array(100)
    let str = ''
    for (i in arr) {
      str += i
    }
  })
  .add('for', () => {
    let arr = new Array(100)
    let str = ''
    for (let i = 0, l = arr.length; i < l; i++) {
      str += i
    }
  })
...

代碼運(yùn)行結(jié)果如下:

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

由運(yùn)行結(jié)果可以看出我們可以盡量使用for...in或者forEach循環(huán),減少使用for循環(huán)。

減少判斷層級(jí)

減少判斷層級(jí)就是減少一些if語(yǔ)句的嵌套,如果是一些必要的條件我們可以通過(guò)單層if結(jié)合return直接跳出函數(shù)的執(zhí)行,關(guān)于優(yōu)化前與優(yōu)化后的代碼執(zhí)行比對(duì)如下所示:

...
/*** 
 接收兩類文件,zip 和 rar* 
 壓縮包的大小限制為 10 兆* 
/

suite
  .add('嵌套寫(xiě)法', () => {
    function uploadFile(suffix, size) {
      // 允許上傳的后綴名
      const suffixList = ['.zip', '.rar']
      const M = 1024*  1024

      if (suffixList.includes(suffix)) {
        if (size <= 10*  M) {
          return '下載成功'
        }
      }
    }
    uploadFile('.zip', 1*  1024*  1024)
  })
  .add('減少判斷寫(xiě)法', () => {
    function uploadFile(suffix, size) {
      // 允許上傳的后綴名
      const suffixList = ['.zip', '.rar']
      const M = 1024*  1024
      if (!suffixList.includes(suffix)) return
      if (size > 10*  M) return
      return '下載成功'
    }
    uploadFile('.zip', 1*  1024*  1024)
  })
...

代碼運(yùn)行結(jié)果如下:

嵌套寫(xiě)法 x 888,445,014 ops/sec ±2.48% (88 runs sampled)
減少判斷寫(xiě)法 x 905,763,884 ops/sec ±1.35% (92 runs sampled)
最快的是:減少判斷寫(xiě)法,嵌套寫(xiě)法

雖然說(shuō)差距并不是很大,但是不適用嵌套的代碼比普通代碼更優(yōu)一些。

減少作用域鏈查找層級(jí)

減少代碼中作用域鏈的查找也是代碼優(yōu)化的一種方法,如下代碼展示了兩者的區(qū)別:

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

代碼運(yùn)行結(jié)果如下:

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

上面代碼只是為了展示區(qū)別,并沒(méi)有實(shí)際意義。

減少數(shù)據(jù)讀取次數(shù)

如果對(duì)象中的某個(gè)數(shù)據(jù)在一個(gè)代碼塊中使用兩遍以上,這樣的話將其進(jìn)行緩存從而減少數(shù)據(jù)的讀取次數(shù)來(lái)達(dá)到更優(yōu)的一個(gè)性能,

測(cè)試代碼如下:

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

代碼運(yùn)行結(jié)果如下:

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

字面量與構(gòu)造式

凡是可以使用字面量方式聲明的內(nèi)容,絕對(duì)是不可以使用構(gòu)造函數(shù)的方式聲明的,兩者在性能方面相差甚遠(yuǎn),代碼如下:

...
suite
  .add('before', () => {
    var str = new String('string')
  })
  .add('after', () => {
    var str = 'string'
  })
...

代碼運(yùn)行結(jié)果如下:

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

到此這篇關(guān)于總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips的文章就介紹到這了,更多相關(guān)JavaScript優(yōu)化tips內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論