Ringkasan dan perkongsian 10 petua pengoptimuman kod JavaScript

WBOY
Lepaskan: 2022-08-01 15:00:38
ke hadapan
1579 orang telah melayarinya

Artikel ini membawa anda pengetahuan yang berkaitan tentang javascript terutamanya memperkenalkan dan meringkaskan 10 petua pengoptimuman kod JavaScript. Artikel ini memperkenalkan kandungan secara terperinci di sekitar tema, yang mempunyai nilai rujukan tertentu semua orang.

Ringkasan dan perkongsian 10 petua pengoptimuman kod JavaScript

[Cadangan berkaitan: tutorial video javascript, bahagian hadapan web]

Tulis di hadapan

Untuk mencapai pengoptimuman kod JavaScript, perkara pertama yang anda perlu lakukan ialah menguji masa pelaksanaan kod JavaScript dengan tepat. Sebenarnya, apa yang perlu dilakukan ialah mengumpul sejumlah besar sampel pelaksanaan untuk statistik dan analisis matematik Di sini kami menggunakan benchmark.js untuk mengesan pelaksanaan kod.

Mula-mula kita perlu memasang kebergantungan dalam projek, kodnya adalah seperti berikut:

yarn add benchmark --save
# 或者
npm i benchmark --save
Salin selepas log masuk

Kemudian kami menulis kod ujian seperti berikut:

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 })

复制代码
Salin selepas log masuk

Hasil pelaksanaan kod adalah seperti berikut:

// join1000 x 146,854 ops/sec ±1.86% (88 larian sampel)
// join10000 x 16,083 ops/sec ±1.06% (92 larian sampel)
// Yang terpantas ialah: join1000

Dalam hasilnya, ops/sec mewakili bilangan pelaksanaan sesaat, Sudah tentu, lebih besar lebih baik, diikuti dengan perbezaan peratusan antara masa pelaksanaan atas dan bawah sesaat, dan akhirnya kandungan dalam kurungan menunjukkan jumlah sampel. Kita boleh lihat prestasi join1000 lebih baik (saya rasa macam mengarut).

Gunakan pembolehubah global dengan berhati-hati

Pembolehubah global yang dinyatakan di sini harus digunakan dengan berhati-hati Mengapa kita harus menggunakannya dengan berhati-hati? Perkara utama adalah seperti berikut:

  • Pembolehubah global ditakrifkan dalam konteks pelaksanaan global dan merupakan bahagian atas semua rantaian skop. Setiap kali anda mencari, anda perlu mencari bahagian teratas secara tempatan, yang memakan masa .
  • Konteks pelaksanaan global sentiasa wujud dalam timbunan pelaksanaan konteks dan tidak akan dimusnahkan sehingga program keluar, yang merupakan pembaziran ruang memori.
  • Jika pembolehubah dengan nama yang sama muncul dalam skop setempat, ia akan meliputi atau mencemarkan pembolehubah global.

Mari kita tulis sekeping kod untuk melihat perbezaan kecekapan pelaksanaan antara pembolehubah global dan pembolehubah reka letak Kodnya adalah seperti berikut:

...
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
    }
  })
...
Salin selepas log masuk

Keputusan berjalan kod adalah seperti berikut:

Pembolehubah global x 158,697 ops/s ±1.05% (87 larian sampel)
Pembolehubah setempat x 160,697 ops/sec ±1.03sec % (90 larian sampel)
Yang terpantas ialah: pembolehubah tempatan

Walaupun perbezaannya tidak besar, kita dapat merasakan bahawa prestasi pembolehubah global adalah lebih teruk daripada pembolehubah tempatan.

Tambah kaedah melalui prototaip

Apabila menambah kaedah yang diperlukan contohnya objek kepada pembina, cuba tambahkannya menggunakan prototaip dan bukannya menambahnya di dalam pembina Kita boleh melihat kod ujian berikut :

...
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()
  })
...
Salin selepas log masuk

Keputusan berjalan kod adalah seperti berikut:

x 573,786 ops/sec ±1.97% (89 larian sampel) ditambah di dalam pembina
Cara Prototaip untuk menambah secara dalaman Memandangkan penutupan akan menyebabkan pembolehubah dalam fungsi disimpan dalam ingatan, yang menggunakan banyak memori, penutupan tidak boleh disalahgunakan, jika tidak, ia akan menyebabkan masalah prestasi pada halaman web, malah boleh menyebabkan kepada kebocoran ingatan. Penyelesaiannya adalah untuk memadam semua pembolehubah tempatan yang tidak digunakan sebelum keluar dari fungsi (iaitu, menetapkan semula pembolehubah tempatan kepada
).

Elakkan menggunakan kaedah akses harta

Dalam objek dalam JavaScript, elakkan menggunakan beberapa kaedah akses harta Ini kerana semua sifat dalam JavaScript boleh dilihat secara luaran.

null

Kod sampel adalah seperti berikut:

Hasil menjalankan kod adalah seperti berikut:

...
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
  })
...
Salin selepas log masuk
Gunakan kaedah capaian atribut x 406,682 ops/sec ±2.33% (82 larian sampel)

Tanpa menggunakan kaedah capaian harta 🎜>untuk pengoptimuman gelung

Apabila kita menggunakan gelung for, kami boleh menyimpan beberapa data yang diperlukan, seperti atribut seperti
, jadi kami tidak perlu mendapatkannya setiap kali kami menilai, dengan itu mengoptimumkan kod kami.



Kod sampel adalah seperti berikut:

Hasil jalankan kod adalah seperti berikut: arr.length

Jujukan ke hadapan x 1,322,889 ops /saat ±1.36% (86 larian sampel)Cache x 1,356,696 ops/saat ±0.70% (92 larian sampel)

Cara lain untuk menulis cache x 1,383,096 ops/sec 93 larian sampel)
...
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
    }
  })
...
Salin selepas log masuk
Terpantas ialah: cara lain untuk menulis cache

Pilih kaedah gelung optimum

Gelung yang biasa kita gunakan sekarang termasuk

,
dan
Gelung, yang manakah antara jenis ini mempunyai prestasi terbaik Kod ujian adalah seperti berikut:

Keputusan yang dijalankan adalah seperti berikut:

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)
  })
...
Salin selepas log masuk

代码运行结果如下:

嵌套写法 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()
  })
...
Salin selepas log masuk

代码运行结果如下:

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()
  })
...
Salin selepas log masuk

代码运行结果如下:

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;
  })
...
Salin selepas log masuk

代码运行结果如下:

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前端

Atas ialah kandungan terperinci Ringkasan dan perkongsian 10 petua pengoptimuman kod JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:jb51.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan