React harusComponentUpdate demystified

Semasa berkembang di React adakah anda pernah tertanya-tanya kapan dan mengapa kaedah render () komponen dijalankan? Atau bila hendak menggunakan kaedah kitaran hidup yang kurang jelas harusComponentUpdate ()?

Sekiranya jawapannya ya, aplikasi anda mungkin menghadapi masalah prestasi. Baca dan anda akan dapat memperbaikinya dengan mudah.

Semuanya datang kepada bagaimana React berfungsi di bawah tudung. Janji besar React adalah bahawa ia cepat menghasilkan elemen pada halaman.

Untuk melakukan ini, React akan mengingat dua versi DOM:

  • versi DOM yang dipaparkan pada masa ini
  • versi DOM seterusnya yang akan dipaparkan

Ia membandingkan keduanya dan mengemas kini DOM yang dipaparkan dengan hanya bahagian yang telah berubah. Proses ini dipanggil pendamaian pokok. Akar pokok yang dinilai untuk pendamaian adalah komponen yang telah berubah.

Hebat. Sekarang sama ada anda merencanakannya atau tidak, aplikasi web anda mengikut komponen kontena / persembahan yang dibahagikan hingga tahap tertentu. Lihat di sini dan di sini untuk definisi. Ini bermaksud bahawa setiap paparan kompleks dalam aplikasi anda dibuat dari komponen wadah yang memegang logik dan mempunyai banyak komponen paparan hanya sebagai kanak-kanak.

Ini adalah corak yang sangat baik. Sekiranya anda melihat lebih dekat walaupun ini bermaksud bahawa setiap interaksi pengguna pada paparan akan mempengaruhi wadah itu sendiri dan mencetuskan pemberiannya dan semua anak-anaknya. Katakan anda mempunyai senarai elemen dengan paparan teks, gambar dan butang bintang kuning "Tambah ke kegemaran" yang mewah. Model minimum untuk elemen senarai ialah:

product = { imageUrl: '...', title: '...', isFavourite: false }

Senarai kegemaran boleh berasal dari sumber data lain. Walau apa pun, organisasi komponen anda mungkin kelihatan seperti ini:

Penangan dipanggil apabila klik pengguna dan menyimpan bahagian pelayan maklumat (atau bertahan di kedai atau apa sahaja) dan mencetuskan perubahan dalam elemen ini.props.elements

Hasil satu klik mencetuskan rendering wadah dan semua baris dalam senarai hanya untuk mengemas kini satu kotak pilihan.

Di sinilah seharusnyaComponentUpdate () dimainkan. Anda boleh memberitahu React agar tidak membuat baris yang tidak perlu menggunakan kaedah ini.

class ListItem extends Component { shouldComponentUpdate(nextProps, nextState) { return nextProps.isFavourite != this.props.isFavourite; } ... }

Berikut adalah kes konkrit: pada projek aplikasi pasar, kami mempunyai pandangan pengurusan produk untuk penjual. Daftar tersebut mempunyai corak "muat lebih banyak ketika pengguna menatal ke bawah" dan tindakan item sebaris "tunjukkan / sembunyikan" untuk menetapkan keterlihatan setiap produk. Semuanya baik-baik saja ketika penjual yang menguruskan <100 produk di papan pemuka mereka. Kemudian penjual tertentu mula memasuki dan mengiklankan lebih dari 300 produk ...

Terdapat jeda ~ 600ms sebelum UI dikemas kini setelah pengguna mengklik ikon "aktifkan / lumpuhkan". Kelewatan itu pasti dapat dilihat oleh pengguna akhir. Dengan menggunakan profiler Chrome, kami melihat bahawa memerlukan React ~ 2ms untuk menghasilkan satu baris. Kali 300 ... kita mendapat sehingga 600ms. Kami menambahkan semestinya checkComponentUpdate () untuk keadaan yang betul. Masa rendering selepas klik pengguna kurang dari 10ms…

Saya telah mengumpulkan satu projek kecil yang membolehkan mengemukakan semula kes ini di sini. Jalankan dan baca komen kod untuk melihat keajaiban berlaku.

Amaran untuk pengguna Redux

Masalah yang dijelaskan di atas mungkin berlaku lebih kerap jika anda menggunakan Redux dan memilih semula (atau perpustakaan saluran tindakan "berasaskan kedai" yang serupa).

Dengan Redux dan pilih semula anda mendorong tindakan ke kedai dan anda memasang pendengar untuk menyimpan perubahan, alias pemilih. Pemilih tersedia secara global dalam aplikasi dan pada aplikasi yang besar, sangat mudah bagi banyak komponen untuk dipetakan ke pemilih yang sama. Perubahan pada kedai boleh mencetuskan perubahan alat peraga dan dengan itu menjadikannya sama sekali tidak relevan untuk beberapa komponen.

Inilah nasihat yang membingungkan: jangan gunakan harusComponentUpdate () untuk mengelakkan rendering dalam kes seperti itu. Logik di dalam harusComponentUpdate hanya perlu melihat apa yang relevan dengan komponen. Ia tidak boleh menjangkakan konteks yang digunakan komponen tersebut. Sebabnya hanya kerana kod anda cepat tidak dapat dicapai.

Sekiranya anda menghadapi masalah seperti ini, ini bermaksud struktur kedai anda salah atau pemilih tidak cukup spesifik. Anda perlu ke pusingan pemodelan baru.

Saya mengesyorkan garis panduan plat boiler yang hebat ini. Ini mempromosikan enkapsulasi kedai per wadah peringkat tinggi dengan kawasan global untuk struktur data utama yang merangkumi seluruh aplikasi. Ini adalah kaedah yang cukup selamat untuk mengelakkan kesilapan pemodelan kedai.

Terima kasih untuk membaca! Sekiranya anda suka, tekan butang bertepuk di bawah. Ia membantu orang lain melihat kisahnya.