Rumah >hujung hadapan web >tutorial js >Mengoptimumkan prestasi bertindak balas dengan komponen tanpa statistik

Mengoptimumkan prestasi bertindak balas dengan komponen tanpa statistik

Lisa Kudrow
Lisa Kudrowasal
2025-02-16 11:35:08267semak imbas

Optimizing React Performance with Stateless Components

Optimizing React Performance with Stateless Components Artikel ini meneroka komponen tanpa kerakyatan dalam React. Komponen jenis ini tidak mengandungi panggilan

, dan hanya memproses "prop" dan komponen kanak -kanak yang masuk.

this.state = { ... }

Ringkasan mata utama

Komponen tanpa kerakyatan dalam React tidak mengandungi sebarang panggilan
    . Mereka hanya mengendalikan "prop" dan subkomponen yang masuk, yang menjadikannya lebih mudah dan mudah untuk dianalisis dari perspektif ujian.
  • this.state = { … } Komponen tanpa kerakyatan boleh ditukar menjadi komponen fungsional, yang lebih seperti JavaScript tulen dan kurang ketergantungan pada rangka kerja yang digunakan.
  • Prestasi komponen tanpa kerakyatan boleh dioptimumkan dengan menggunakan react.purecomponent, yang mempunyai kaedah terbina dalam
  • yang membolehkan perbandingan cetek setiap prop.
  • shouldComponentUpdate Recompose adalah perpustakaan utiliti untuk komponen fungsi dan komponen lanjutan dalam React. Ia boleh digunakan untuk menjadikan komponen fungsi tanpa membuat semula apabila prop tidak berubah.
  • Komponen tanpa stateless dapat meningkatkan prestasi aplikasi React dengan ketara kerana mereka tidak menguruskan kaedah negeri atau kitaran hayat mereka sendiri, dengan itu mengurangkan jumlah kod dan penggunaan memori. Walau bagaimanapun, mereka juga mempunyai beberapa batasan, seperti tidak dapat menggunakan kaedah kitaran hayat atau menguruskan keadaan mereka sendiri.
Asas

<code class="language-javascript">import React, { Component } from 'react'

class User extends Component {
  render() {
    const { name, highlighted, userSelected } = this.props
    console.log('Hey User is being rendered for', [name, highlighted])
    return <div>
      <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
           userSelected()
         }}>
        {name}
      </h3>
    </div>
  }
}</code>

Kod berjalan secara normal. Ia sangat asas, tetapi ia membina contoh.

Perlu diperhatikan:

Ia tidak bertauliah, tanpa
    .
  • this.state = { ... }
  • digunakan untuk memahami penggunaannya. Terutamanya apabila melakukan pengoptimuman prestasi, jika props tidak benar-benar berubah, penyerahan semula yang tidak perlu perlu dielakkan.
  • console.log Pengendali acara di sini adalah "inline". Sintaks ini mudah kerana kodnya hampir dengan unsur -unsur yang diprosesnya, dan sintaks ini bermakna anda tidak perlu melakukan apa -apa
  • .
  • .bind(this) menggunakan fungsi sebaris sedemikian akan mempunyai sedikit kehilangan prestasi, kerana fungsi mesti dibuat setiap kali ia diberikan. Ini akan terperinci kemudian.
Komponen paparan

sekarang kita menyedari bahawa komponen di atas bukan sahaja tanpa stat, ia sebenarnya adalah apa yang Dan Abramov memanggil komponen paparan. Ia hanya nama, tetapi pada dasarnya, ia ringan, menghasilkan beberapa HTML/DOM dan tidak mengendalikan sebarang data keadaan.

Jadi kita boleh membuatnya menjadi fungsi! Bukan sahaja ini terasa "sejuk", ia juga menjadikannya kurang mengerikan kerana lebih mudah difahami. Ia menerima input dan, secara bebas dari alam sekitar, sentiasa mengembalikan output yang sama. Sudah tentu, ia "panggilan balik" kerana salah satu alat peraga adalah fungsi yang boleh dipanggil.

mari kita menulis semula:

<code class="language-javascript">import React, { Component } from 'react'

class User extends Component {
  render() {
    const { name, highlighted, userSelected } = this.props
    console.log('Hey User is being rendered for', [name, highlighted])
    return <div>
      <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
           userSelected()
         }}>
        {name}
      </h3>
    </div>
  }
}</code>

Rasanya baik, bukan? Rasanya seperti JavaScript tulen, anda boleh menulisnya tanpa memikirkan rangka kerja yang anda gunakan.

Masalah pengubahsuaian semula berterusan

Katakan komponen pengguna kami digunakan dalam komponen yang mengubah keadaan dari masa ke masa. Tetapi keadaan tidak menjejaskan komponen kita. Contohnya, seperti ini:

<code class="language-javascript">const User = ({ name, highlighted, userSelected }) => {
  console.log('Hey User is being rendered for', [name, highlighted])
  return <div>
    <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
         userSelected()
       }}>
      {name}
    </h3>
  </div>
}</code>

Jalankan kod ini dan anda akan melihat bahawa walaupun tiada perubahan, komponen kami akan diberikan semula! Ini bukan masalah besar sekarang, tetapi dalam aplikasi praktikal, komponen cenderung menjadi lebih dan lebih kompleks, dan setiap penanaman semula yang tidak perlu akan menyebabkan laman web melambatkan.

Jika anda menggunakan react-addons-perf untuk menyahpepijat aplikasi ini sekarang, saya pasti anda akan mendapati masa itu dibazirkan pada rendering Users->User. Alamak! Apa yang perlu dilakukan? !

Nampaknya segala -galanya menunjukkan bahawa kita perlu menggunakan shouldComponentUpdate untuk menampung bagaimana reaksi berfikir prop berbeza, dan kita pasti mereka tidak berbeza. Untuk menambah cangkuk kitaran hayat React, komponen perlu menjadi kelas. Alas . Oleh itu, kami kembali ke pelaksanaan berasaskan kelas asal dan menambah kaedah cangkuk kitaran hayat baru:

Kembali ke Komponen Kelas

<code class="language-javascript">import React, { Component } from 'react'

class Users extends Component {
  constructor(props) {
    super(props)
    this.state = {
      otherData: null,
      users: [{name: 'John Doe', highlighted: false}]
    }
  }

  async componentDidMount() {
    try {
      let response = await fetch('https://api.github.com')
      let data = await response.json()
      this.setState({otherData: data})
    } catch(err) {
      throw err
    }
  }

  toggleUserHighlight(user) {
    this.setState(prevState => ({
      users: prevState.users.map(u => {
        if (u.name === user.name) {
          u.highlighted = !u.highlighted
        }
        return u
      })
    }))
  }

  render() {
    return <div>
      <h1>Users</h1>
      {
        this.state.users.map(user => {
          return <user name="{user.name}" highlighted="{user.highlighted}" userselected="{()"> {
              this.toggleUserHighlight(user)
            }}/>
         })
      }
    </user>
</div>
  }
}</code>

Perhatikan kaedah shouldComponentUpdate yang baru ditambah. Ini agak hodoh. Bukan sahaja kita tidak lagi menggunakan fungsi, tetapi kita juga perlu menyenaraikan alat peraga secara manual yang boleh diubah. Ini melibatkan andaian berani bahawa prop fungsi userSelected tidak akan berubah. Ini tidak mungkin, tetapi ia memerlukan perhatian.

Tetapi sila ambil perhatian bahawa walaupun komponen aplikasi yang disertakan semula, ini hanya akan diberikan sekali! Jadi, ini bagus untuk prestasi. Tetapi bolehkah kita melakukan yang lebih baik?

React.PureComponent

Sejak React 15.3, terdapat kelas asas komponen baru. Ia dipanggil PureComponent, dan ia mempunyai kaedah terbina dalam shouldComponentUpdate yang membuat "perbandingan cetek" setiap prop. Luar Biasa! Jika kita menggunakan ini, kita boleh membuang kaedah Custom shouldComponentUpdate kita yang mesti menyenaraikan prop khusus.

<code class="language-javascript">import React, { Component } from 'react'

class User extends Component {
  render() {
    const { name, highlighted, userSelected } = this.props
    console.log('Hey User is being rendered for', [name, highlighted])
    return <div>
      <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
           userSelected()
         }}>
        {name}
      </h3>
    </div>
  }
}</code>

cuba dan anda akan kecewa. Ia semula setiap kali. Kenapa? ! Jawapannya adalah kerana fungsi userSelected dicipta semula setiap kali dalam kaedah render aplikasi. Ini bermakna bahawa apabila komponen berasaskan PureComponent memanggil sendiri shouldComponentUpdate(), ia kembali true, kerana fungsi itu sentiasa berbeza, kerana ia dicipta setiap kali.

Biasanya, penyelesaian kepada masalah ini adalah untuk mengikat fungsi dalam pembina yang mengandungi komponen. Pertama, jika kita melakukan ini, ini bermakna kita perlu menaip nama kaedah 5 kali (dan 1 sebelum):

  • this.userSelected = this.userSelected.bind(this) (dalam pembina)
  • userSelected() { ... } (sebagai definisi kaedah itu sendiri)
  • <user ... userselected="{this.userSelected}"></user> (di mana rendering komponen pengguna ditakrifkan)

Satu lagi masalah ialah, seperti yang anda lihat, apabila kaedah userSelected sebenarnya dilaksanakan, ia bergantung pada penutupan. Khususnya, ia bergantung kepada pembolehubah skop this.state.users.map() dari iterator. user

diakui, ada penyelesaian untuk masalah ini, yang terlebih dahulu mengikat kaedah

untuk userSelected dan kemudian apabila kaedah dipanggil (dalam komponen kanak -kanak), lulus this (atau namanya ) kembali. Berikut adalah penyelesaian seperti ini. user

Kembali semula untuk menyelamatkan!

Pertama, mari kita semak matlamat kami:

  1. Menulis komponen berfungsi terasa lebih baik kerana ia berfungsi. Ini segera memberitahu pembaca kod bahawa ia tidak menyelamatkan mana -mana negeri. Mereka mudah untuk alasan dari perspektif ujian unit. Dan mereka berasa lebih ringkas dan lebih seperti JavaScript tulen (dan tentu saja JSX).
  2. Kami terlalu malas untuk mengikat semua kaedah yang diluluskan kepada komponen kanak -kanak. Sudah tentu, jika kaedahnya kompleks, lebih baik untuk refactor mereka dan bukannya mencipta mereka secara dinamik. Kaedah penciptaan dinamik bermakna kita boleh menulis kod mereka secara langsung di mana ia digunakan, kita tidak perlu menamakannya, dan kita tidak menyebutnya 5 kali di tiga tempat yang berbeza.
  3. Subkomponen harus diberikan semula hanya apabila prop berubah. Ini mungkin tidak penting untuk komponen kecil dan cepat, tetapi untuk aplikasi praktikal, apabila anda mempunyai banyak komponen ini, semua cpu pembaziran tambahan ini boleh dielakkan.
  4. (sebenarnya, keadaan ideal kita adalah bahawa komponen hanya diberikan sekali. Mengapa tidak dapat bertindak balas menyelesaikan masalah ini untuk kita? .)

Menurut dokumentasi, rekomposnya adalah "Perpustakaan Alat Utiliti React untuk komponen fungsi dan komponen lanjutan. Fikirkannya sebagai lodash untuk React."

. Terdapat banyak untuk diterokai di perpustakaan ini, tetapi sekarang kami ingin menjadikan komponen fungsi kami tanpa membuat semula apabila alat peraga tidak berubah.

Kali pertama kami cuba menulis semula kepada komponen fungsi dengan rekomposisi.pure, nampaknya ini:

<code class="language-javascript">import React, { Component } from 'react'

class User extends Component {
  render() {
    const { name, highlighted, userSelected } = this.props
    console.log('Hey User is being rendered for', [name, highlighted])
    return <div>
      <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
           userSelected()
         }}>
        {name}
      </h3>
    </div>
  }
}</code>

dan

kekunci) tidak berubah.

name mari kita melangkah lebih jauh. Kami tidak menggunakan highlighted, tetapi kami menggunakan

, yang merupakan versi

, tetapi anda boleh menentukan kunci prop yang anda ingin fokus pada: recompose.pure recompose.onlyUpdateForKeys recompose.pure

<code class="language-javascript">const User = ({ name, highlighted, userSelected }) => {
  console.log('Hey User is being rendered for', [name, highlighted])
  return <div>
    <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
         userSelected()
       }}>
      {name}
    </h3>
  </div>
}</code>

atau

props berubah. Sekiranya komponen induknya diperuntukkan semula, komponen pengguna tidak.

name Long live! Kami menjumpai emas! highlighted

Perbincangan

Pertama, tanya diri anda jika ia patut mengoptimumkan prestasi komponen anda. Mungkin itu lebih daripada itu. Komponen anda harus ringan, mungkin anda boleh memindahkan apa -apa pengiraan yang mahal daripada komponen dan memindahkannya ke fungsi yang tidak dapat dilupakan luaran, atau anda boleh menyusun semula komponen anda supaya sesetengah data tidak boleh membuang komponen rendering apabila digunakan. Sebagai contoh, dalam contoh ini, anda mungkin tidak mahu menjadikan komponen pengguna sebelum mengambilnya.

Menulis kod dengan cara yang paling mudah untuk anda, kemudian memulakan program anda dan melangkah dari sana untuk menjadikannya lebih baik bukan penyelesaian yang buruk. Dalam contoh ini, untuk meningkatkan prestasi, anda perlu menentukan komponen fungsi dari:

<code class="language-javascript">import React, { Component } from 'react'

class User extends Component {
  render() {
    const { name, highlighted, userSelected } = this.props
    console.log('Hey User is being rendered for', [name, highlighted])
    return <div>
      <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
           userSelected()
         }}>
        {name}
      </h3>
    </div>
  }
}</code>

... ditukar kepada ...

<code class="language-javascript">const User = ({ name, highlighted, userSelected }) => {
  console.log('Hey User is being rendered for', [name, highlighted])
  return <div>
    <h3 style="{{fontStyle:" highlighted : onclick="{event"> {
         userSelected()
       }}>
      {name}
    </h3>
  </div>
}</code>

Sebaik -baiknya, bukannya menunjukkan cara untuk memintas masalah, penyelesaian terbaik adalah patch baru dari React, yang membuat peningkatan yang besar kepada shallowEqual untuk "secara automatik" mengenal pasti masuk dan membandingkan adalah fungsi, dan hanya kerana Ia tidak sama tidak bermakna bahawa ia sebenarnya berbeza.

setuju! Terdapat alternatif kompromi untuk berurusan dengan fungsi sebaris yang mengikat kaedah dalam pembina dan setiap rekreasi. Itulah bidang kelas awam. Ia adalah ciri Fasa 2 di Babel, jadi persediaan anda mungkin akan menyokongnya. Sebagai contoh, di sini adalah cawangan yang menggunakannya, yang bukan sahaja lebih pendek, tetapi sekarang juga bermakna kita tidak perlu menyenaraikan semua alat bukan fungsi secara manual. Penyelesaian ini mesti meninggalkan penutupan. Walau bagaimanapun, masih bagus untuk mengetahui dan menyedari recompose.onlyUpdateForKeys apabila diperlukan.

Untuk maklumat lanjut mengenai React, sila lihat kursus kami "React the ES6 Way".

Artikel ini telah dikaji semula oleh Jack Franklin. Terima kasih kepada semua pengulas rakan sebaya untuk membuat kandungan SitePoint sempurna!

soalan yang sering ditanya mengenai mengoptimumkan prestasi reaksi dengan komponen tanpa stat. Apakah perbezaan utama antara komponen negara dan komponen tanpa statistik dalam React?

Komponen negeri (juga dikenali sebagai komponen kelas) mengekalkan ingatan mengenai perubahan dalam keadaan komponen dari masa ke masa. Mereka bertanggungjawab untuk bagaimana komponen berkelakuan dan diberikan. Sebaliknya, komponen tanpa kerakyatan (juga dipanggil komponen berfungsi) tidak mempunyai keadaan sendiri. Mereka menerima data dari komponen induk dalam bentuk prop dan menjadikannya. Mereka bertanggungjawab terutamanya untuk bahagian UI komponen.

Bagaimana untuk mengoptimumkan prestasi aplikasi React saya menggunakan komponen tanpa kerakyatan?

Komponen tanpa stateless dapat meningkatkan prestasi aplikasi React. Oleh kerana mereka tidak menguruskan kaedah negeri atau kitaran hayat mereka sendiri, mereka mempunyai kod yang kurang, yang menjadikan mereka lebih mudah difahami dan diuji. Mereka juga boleh mengurangkan jumlah memori yang digunakan oleh permohonan. Untuk mengoptimumkan prestasi, anda boleh menukar komponen negeri ke komponen tanpa statistik sebanyak mungkin dan menggunakan React's

untuk mengelakkan penyampaian semula yang tidak perlu.

Apakah pureComponent dan bagaimana ia membantu mengoptimumkan prestasi bertindak balas?

PureComponent adalah komponen reaksi khas yang membantu mengoptimumkan prestasi aplikasi anda. Ia menggunakan perbandingan prop dan negara cetek untuk melaksanakan kaedah shouldComponentUpdate kitaran hayat. Ini bermakna ia akan membuat semula hanya apabila keadaan atau props berubah, yang dapat mengurangkan penampilan semula yang tidak perlu dan meningkatkan prestasi.

Bagaimana untuk menukar komponen keadaan dalam React kepada komponen tanpa kewarganegaraan?

Menukar komponen negeri ke komponen tanpa kewarganegaraan termasuk mengeluarkan kaedah negeri atau kitaran hayat dari komponen. Komponen hanya perlu menerima data melalui alat peraga dan menjadikannya. Berikut adalah contoh:

// komponen status Kelas Selamat Datang memanjangkan React.Component { render () { kembali

hello, {this.props.name}
; } }

// komponen tanpa stat fungsi selamat datang (props) { kembali

hello, {props.name}
; }

Apakah amalan terbaik untuk menggunakan komponen tanpa kerakyatan dalam React?

Beberapa amalan terbaik untuk menggunakan komponen tanpa statistik dalam React termasuk: Gunakan seberapa banyak yang mungkin untuk meningkatkan prestasi dan kebolehbacaan; Ia juga disyorkan untuk menggunakan dekonstruksi prop untuk menulis kod bersih.

Bolehkah komponen tanpa kerakyatan menggunakan kaedah kitaran hayat dalam React?

Tidak, komponen tanpa kerakyatan tidak boleh menggunakan kaedah kitaran hayat dalam React. Kaedah kitaran hayat hanya boleh digunakan untuk komponen kelas. Walau bagaimanapun, dengan pengenalan cangkuk dalam React 16.8, kini anda boleh menambah ciri -ciri keadaan dan kitaran hayat untuk berfungsi komponen.

Apakah batasan komponen tanpa statistik dalam React?

Walaupun komponen tanpa kerakyatan mempunyai banyak kelebihan, mereka juga mempunyai beberapa batasan. Mereka tidak boleh menggunakan kaedah kitaran hayat atau menguruskan keadaan mereka sendiri. Walau bagaimanapun, batasan -batasan ini dapat diatasi dengan menggunakan cangkuk Reacts.

Bagaimanakah komponen tanpa stat dapat meningkatkan kebolehbacaan kod?

Komponen tanpa statik meningkatkan kebolehbacaan kod melalui kesederhanaan dan kejelasan. Mereka tidak menguruskan keadaan mereka sendiri atau menggunakan kaedah kitaran hayat, yang menjadikannya lebih mudah dan mudah difahami. Mereka juga menggalakkan penggunaan komponen kecil dan boleh diguna semula, yang boleh menjadikan kod lebih teratur dan lebih mudah untuk dikekalkan.

Bolehkah komponen tanpa statur mengendalikan peristiwa dalam React?

Ya, komponen tanpa kerakyatan boleh mengendalikan peristiwa dalam React. Pengendali acara boleh diluluskan sebagai alat peraga kepada komponen tanpa stat. Berikut adalah contoh:

fungsi ActionLink (props) { Kembali ( Klik saya ); }

Bagaimanakah komponen tanpa kerakyatan mempromosikan modularization kod?

Komponen tanpa statik mempromosikan modularization kod dengan mempromosikan penggunaan komponen kecil dan boleh diguna semula. Setiap komponen boleh dibangunkan dan diuji secara bebas, yang menjadikan kod lebih mudah untuk dikekalkan dan difahami. Ia juga menggalakkan pemisahan kebimbangan, di mana setiap komponen bertanggungjawab untuk satu fungsi.

Atas ialah kandungan terperinci Mengoptimumkan prestasi bertindak balas dengan komponen tanpa statistik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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