Rumah >hujung hadapan web >tutorial js >Cara Melaksanakan Memoisasi dalam Reaksi untuk Meningkatkan Prestasi
kami akan merangkumi perkara berikut:
mata utama
React.PureComponent
React.memo()
Jika fungsi diluluskan sebagai prop kepada komponen kanak-kanak, komponen kanak-kanak akan diberikan semula walaupun React.memo()
useCallback()
Hafalan hendaklah digunakan dengan berhati -hati dalam aplikasi React. Ia berfungsi dengan baik apabila komponen mengembalikan output yang sama kepada alat yang sama, mengandungi pelbagai elemen UI (pemeriksaan DOM maya mempengaruhi prestasi), atau sering menyediakan alat yang sama. DOM biasa pada dasarnya mengandungi satu set nod yang diwakili sebagai pokok. Setiap nod dalam DOM adalah perwakilan elemen UI. Apabila perubahan keadaan berlaku dalam permohonan, nod yang sepadan dengan elemen UI dan semua elemen anaknya dikemas kini di DOM dan kemudian UI dicat semula untuk mencerminkan perubahan yang dikemas kini.
Menggunakan algoritma pokok yang cekap, kemas kini nod lebih cepat, tetapi lukisan semula lebih perlahan, dan apabila DOM mempunyai sejumlah besar elemen UI, ia akan memberi kesan kepada prestasi. Oleh itu, DOM maya diperkenalkan dalam React.
Ini adalah perwakilan maya DOM sebenar. Sekarang, apabila keadaan aplikasi berubah pula, React tidak secara langsung mengemas kini DOM sebenar, tetapi mewujudkan DOM maya baru. React kemudian membandingkan DOM maya baru ini dengan DOM maya yang dibuat sebelum ini untuk mencari perbezaan yang perlu direkodkan.
Menggunakan perbezaan ini, DOM maya akan mengemas kini DOM sebenar dengan perubahan. Ini meningkatkan prestasi kerana DOM maya tidak hanya mengemas kini elemen UI dan semua elemen anaknya, tetapi hanya mengemas kini hanya perubahan minimum yang diperlukan dalam DOM sebenar.
Di bahagian sebelumnya, kita melihat bagaimana React dapat melaksanakan kemas kini DOM dengan berkesan menggunakan DOM maya untuk meningkatkan prestasi. Dalam bahagian ini, kita akan melihat kes penggunaan yang menjelaskan mengapa ingatan diperlukan untuk meningkatkan prestasi.
Kami akan membuat kelas induk dengan butang untuk meningkatkan pembolehubah negeri bernama Count. Komponen induk juga memanggil komponen kanak -kanak dan melepasi prop kepadanya. Kami juga menambah pernyataan konsol.log () kepada kaedah render dua kelas:
<code class="language-javascript">//Parent.js class Parent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } handleClick = () => { this.setState((prevState) => { return { count: prevState.count + 1 }; }); }; render() { console.log("Parent render"); return ( <div classname="App"> <button onclick="{this.handleClick}">Increment</button> <h2>Count: {this.state.count}</h2> <child name='{"joe"}'></child> </div> ); } } export default Parent;</code>
Kod penuh untuk contoh ini boleh didapati di CodeSandbox.
kami akan membuat kelas kanak -kanak yang mengambil prop yang diluluskan oleh komponen induk dan memaparkannya dalam UI:
<code class="language-javascript">//Child.js class Child extends React.Component { render() { console.log("Child render"); return ( <div> <h2>Name: {this.props.name}</h2> </div> ); } } export default Child;</code>
Setiap kali kita mengklik butang dalam komponen induk, perubahan nilai kiraan. Oleh kerana ini adalah perubahan keadaan, kaedah render komponen induk dipanggil.
Props yang diluluskan ke subclass tetap tidak berubah setiap kali ibu bapa semula, jadi komponen kanak-kanak tidak boleh diberikan semula. Walau bagaimanapun, apabila kita menjalankan kod di atas dan terus menambah kiraan, kita mendapat output berikut:
<code>Parent render Child render Parent render Child render Parent render Child render</code>
anda boleh meningkatkan kiraan contoh di atas sendiri dalam kotak pasir berikut dan lihat output konsol:
[pautan codesandbox hendaklah tertanam di sini, tetapi kerana saya tidak dapat mengakses laman web luaran, ia tidak dapat disediakan]
Dari output ini, kita dapat melihat bahawa apabila komponen induknya semula, ia juga melukis semula komponen kanak-kanak-walaupun prop yang diserahkan kepada komponen kanak-kanak tidak berubah. Ini akan menyebabkan DOM maya subkomponen melakukan pemeriksaan perbezaan dengan DOM maya sebelumnya. Oleh kerana tidak ada perbezaan dalam komponen kanak -kanak - kerana alat peraga adalah sama dalam semua pelaku semula - DOM sebenar tidak dikemas kini.
Kami mempunyai kelebihan prestasi untuk tidak mengemas kini dom sebenar yang tidak perlu, tetapi kita dapat melihat di sini bahawa DOM maya baru dicipta dan pemeriksaan perbezaan dilakukan walaupun komponen kanak -kanak tidak benar -benar berubah. Untuk komponen reaksi kecil, prestasi ini boleh diabaikan, tetapi untuk komponen yang besar, kesan prestasi adalah hebat. Untuk mengelakkan pemeriksaan semula dan pemeriksaan DOM maya ini, kami menggunakan memori.
Dalam konteks aplikasi React, hafalan adalah teknik di mana setiap kali komponen induk semula, komponen kanak-kanak akan membuat semula hanya apabila prop berubah. Jika alat peraga tidak berubah, ia tidak melaksanakan kaedah render, tetapi mengembalikan hasil cache. Oleh kerana kaedah Render tidak dilaksanakan, tiada DOM maya dan cek pembezaan dicipta - dengan itu meningkatkan prestasi.
Sekarang mari kita lihat bagaimana hafalan dilaksanakan dalam kelas dan komponen React berfungsi untuk mengelakkan penyampaian semula yang tidak perlu ini.
(kandungan berikut adalah serupa dengan teks asal, kecuali bahasa dan ekspresi telah diselaraskan sedikit, dan lokasi dan format imej tidak berubah. Saya tidak dapat memberikan pautan CodeSandbox kerana ketidakupayaan untuk mengakses laman web luaran .)
Untuk melaksanakan memori dalam komponen kelas, kami akan menggunakan React.PureComponent
. React.PureComponent
melaksanakan shouldComponentUpdate()
, yang membuat perbandingan cetek antara negeri dan prop dan membuat komponen bertindak balas hanya jika prop atau perubahan keadaan.
Tukar komponen kanak -kanak ke kod yang ditunjukkan di bawah:
<code class="language-javascript">//Parent.js class Parent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } handleClick = () => { this.setState((prevState) => { return { count: prevState.count + 1 }; }); }; render() { console.log("Parent render"); return ( <div classname="App"> <button onclick="{this.handleClick}">Increment</button> <h2>Count: {this.state.count}</h2> <child name='{"joe"}'></child> </div> ); } } export default Parent;</code>
Kod penuh untuk contoh ini adalah seperti berikut: [pautan codesandbox hendaklah tertanam di sini]
Komponen induk tetap tidak berubah. Sekarang, apabila kita kenaikan kiraan dalam komponen induk, output dalam konsol adalah seperti berikut:
<code class="language-javascript">//Child.js class Child extends React.Component { render() { console.log("Child render"); return ( <div> <h2>Name: {this.props.name}</h2> </div> ); } } export default Child;</code>
Untuk rendering pertama, ia memanggil kaedah render komponen ibu bapa dan kanak -kanak.
Dalam setiap penambahan semula penambahan semula, hanya fungsi render komponen induk dipanggil. Komponen kanak -kanak tidak akan diserahkan.
Untuk melaksanakan memori dalam komponen reaksi berfungsi, kami akan menggunakan React.memo()
. React.memo()
adalah komponen pesanan tinggi (HOC) yang melakukan kerja yang sama untuk PureComponent
untuk mengelakkan penanaman semula yang tidak perlu.
Berikut adalah kod untuk komponen berfungsi:
<code>Parent render Child render Parent render Child render Parent render Child render</code>
Kami juga menukar komponen induk ke komponen berfungsi seperti yang ditunjukkan di bawah:
<code class="language-javascript">//Child.js class Child extends React.PureComponent { // 将React.Component更改为React.PureComponent render() { console.log("Child render"); return ( <div> <h2>Name: {this.props.name}</h2> </div> ); } } export default Child;</code>
Kod penuh untuk contoh ini dapat dilihat di kotak pasir berikut: [pautan codesandbox hendaklah tertanam di sini]
Sekarang, apabila kita kenaikan kiraan dalam komponen induk, konsol mengeluarkan yang berikut:
<code>Parent render Child render Parent render Parent render</code>
React.memo()
masalah dengan fungsi prop Dalam contoh di atas, kita melihat bahawa apabila kita menggunakan React.memo()
hoc untuk komponen kanak-kanak kita, walaupun komponen induknya disampaikan semula, komponen kanak-kanak tidak diberikan semula.
. Mari kita lihat contoh. React.memo()
<code class="language-javascript">//Child.js export function Child(props) { console.log("Child render"); return ( <div> <h2>Name: {props.name}</h2> </div> ); } export default React.memo(Child); // 在此处为子组件添加HOC以进行记忆化</code>Kod subkomponen tetap tidak berubah. Kami tidak menggunakan fungsi yang diluluskan sebagai alat peraga dalam komponen kanak -kanak:
<code class="language-javascript">//Parent.js import React, { useState } from 'react'; import Child from './Child'; export default function Parent() { const [count, setCount] = useState(0); const handleClick = () => { setCount(count + 1); }; console.log("Parent render"); return ( <div> <button onclick="{handleClick}">Increment</button> <h2>Count: {count}</h2> <child name='{"joe"}'></child> </div> ); }</code>Sekarang, apabila kita kenaikan kiraan dalam komponen induk, ia semula dan melahirkan semula komponen kanak-kanak walaupun prop tidak berubah.
Jadi, apa yang menyebabkan komponen kanak-kanak untuk membuat semula? Jawapannya adalah bahawa setiap kali komponen induk semula, fungsi pengendali baru dicipta dan diserahkan kepada komponen kanak-kanak. Sekarang, kerana fungsi pengendali dicipta semula setiap kali ia disusun semula, komponen kanak -kanak akan mendapati bahawa rujukan pengendali telah diubah apabila ia merupakan perbandingan cetek props dan rerenders komponen kanak -kanak.
Di bahagian seterusnya, kita akan melihat bagaimana menyelesaikan masalah ini.
useCallback()
untuk mengelakkan pengubahsuaian lebih lanjut Masalah utama yang menyebabkan komponen kanak-kanak diserahkan semula adalah penciptaan semula fungsi program, yang mengubah rujukan yang disampaikan kepada komponen kanak-kanak. Oleh itu, kita memerlukan cara untuk mengelakkan rekreasi ini. Sekiranya pengendali tidak dicipta semula, rujukan kepada pengendali tidak akan berubah - jadi komponen kanak -kanak tidak akan diserahkan.
3 Cangkuk diperkenalkan dalam React 16. Untuk mengetahui lebih lanjut mengenai cangkuk, anda boleh menyemak dokumentasi Rasmi Rasmi React atau menyemak "React Hooks: Cara Memulakan dan Membina Sendiri."
useCallback()
useCallback()
pertimbangkan contoh
useCallback()
<code class="language-javascript">//Parent.js class Parent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } handleClick = () => { this.setState((prevState) => { return { count: prevState.count + 1 }; }); }; render() { console.log("Parent render"); return ( <div classname="App"> <button onclick="{this.handleClick}">Increment</button> <h2>Count: {this.state.count}</h2> <child name='{"joe"}'></child> </div> ); } } export default Parent;</code>ditambah ke fungsi
. Parameter kedua useCallback()
boleh menjadi array kosong, ketergantungan, atau senarai ketergantungan. Fungsi handleClick()
dicipta semula apabila sebarang kebergantungan yang disebut dalam perubahan parameter kedua. [x,y]
handleClick()
Jika kebergantungan yang disebut dalam
untuk pengendali yang diserahkan kepada komponen kanak -kanak: useCallback()
useCallback()
(ini sama dengan teks asal, kecuali bahasa dan ekspresi diselaraskan sedikit, dan kedudukan imej dan format tidak berubah. Saya tidak dapat menyediakan pautan CodeSandbox kerana ketidakupayaan untuk mengakses laman web luaran.)
Langkah berjaga -jaga
Hafalanmengembalikan output yang sama apabila diberi alat yang sama
bagaimana untuk menjadikan UI dengan reaksi
React.memo()
React.PureComponent
React.memo()
useCallback()
Soalan Lazim Mengenai Restace React
Atas ialah kandungan terperinci Cara Melaksanakan Memoisasi dalam Reaksi untuk Meningkatkan Prestasi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!