Metode Meningkatkan Dan Mengoptimalkan Kinerja Dalam Aplikasi Bereaksi
Diterbitkan: 2022-03-10React memungkinkan aplikasi web untuk memperbarui antarmuka pengguna (UI) mereka dengan cepat, tetapi itu tidak berarti aplikasi React menengah atau besar Anda akan bekerja secara efisien. Performanya akan bergantung pada bagaimana Anda menggunakan React saat membangunnya, dan pada pemahaman Anda tentang bagaimana React beroperasi dan proses yang dilalui komponen melalui berbagai fase siklus hidupnya. React menawarkan banyak peningkatan kinerja pada aplikasi web, dan Anda dapat mencapai peningkatan ini melalui berbagai teknik, fitur, dan alat.
Dalam tutorial ini, kita akan membahas berbagai metode untuk mengoptimalkan kinerja di aplikasi React, dan juga fitur-fitur React yang dapat kita gunakan untuk meningkatkan kinerja.
Di mana Mulai Mengoptimalkan Kinerja Dalam Aplikasi Bereaksi?
Kami tidak dapat mulai mengoptimalkan aplikasi tanpa mengetahui secara pasti kapan dan di mana harus mengoptimalkan. Anda mungkin bertanya, "Di mana kita mulai?"
Selama proses rendering awal, React membangun pohon DOM komponen. Jadi, ketika data berubah di pohon DOM, kami ingin React untuk merender ulang hanya komponen yang terpengaruh oleh perubahan, melewatkan komponen lain di pohon yang tidak terpengaruh.
Namun, React dapat merender ulang semua komponen di pohon DOM, meskipun tidak semua terpengaruh. Ini akan menghasilkan waktu pemuatan yang lebih lama, waktu yang terbuang, dan bahkan sumber daya CPU yang terbuang. Kita perlu mencegah hal ini terjadi. Jadi, di sinilah kami akan memfokuskan upaya optimasi kami.
Dalam situasi ini, kita dapat mengonfigurasi setiap komponen untuk hanya merender atau membedakan bila diperlukan, untuk menghindari pemborosan sumber daya dan waktu.
Mengukur performa
Jangan pernah memulai proses pengoptimalan aplikasi React Anda berdasarkan apa yang Anda rasakan. Sebagai gantinya, gunakan alat pengukuran yang tersedia untuk menganalisis kinerja aplikasi React Anda dan dapatkan laporan mendetail tentang apa yang mungkin memperlambatnya.
Menganalisis Komponen Bereaksi Dengan Tab Kinerja Chrome
Menurut dokumentasi React, saat Anda masih dalam mode pengembangan, Anda dapat menggunakan tab “Performance” di browser Chrome untuk memvisualisasikan bagaimana komponen React dipasang, diperbarui, dan dilepas. Misalnya, gambar di bawah ini menunjukkan profil tab "Kinerja" Chrome dan menganalisis blog saya dalam mode pengembangan.
Untuk melakukannya, ikuti langkah-langkah berikut:
- Nonaktifkan semua ekstensi untuk sementara, terutama React Developer Tools, karena dapat mengacaukan hasil analisis. Anda dapat dengan mudah menonaktifkan ekstensi dengan menjalankan browser Anda dalam mode penyamaran.
- Pastikan aplikasi berjalan dalam mode pengembangan. Artinya, aplikasi harus berjalan di localhost Anda.
- Buka Alat Pengembang Chrome, klik tab "Kinerja", lalu klik tombol "Rekam".
- Lakukan tindakan yang ingin Anda buat profil. Jangan merekam lebih dari 20 detik, jika tidak Chrome dapat hang.
- Hentikan rekaman.
- React event akan dikelompokkan di bawah label “User Timing”.
Angka-angka dari profiler bersifat relatif. Sebagian besar waktu dan komponen akan dirender lebih cepat dalam produksi. Namun demikian, ini akan membantu Anda mengetahui kapan UI diperbarui secara tidak sengaja, serta seberapa dalam dan seberapa sering pembaruan UI terjadi.
React Developer Tools Profiler
Menurut dokumentasi React, di react-dom
16.5+ dan react-native
0.57+, kemampuan profil yang ditingkatkan tersedia dalam mode pengembang menggunakan React Developer Tools Profiler. Profiler menggunakan API Profiler eksperimental React untuk mengumpulkan informasi waktu tentang setiap komponen yang dirender, untuk mengidentifikasi hambatan kinerja dalam aplikasi React.
Cukup unduh React Developer Tools untuk browser Anda, dan kemudian Anda dapat menggunakan alat profiler yang disertakan bersamanya. Profiler hanya dapat digunakan baik dalam mode pengembangan atau dalam pembuatan profil produksi React v16.5+. Gambar di bawah ini adalah ringkasan profiler blog saya dalam mode pengembangan menggunakan React Developer Tools Profiler:
Untuk mencapai ini, ikuti langkah-langkah ini:
- Unduh Alat Pengembang Bereaksi.
- Pastikan aplikasi React Anda dalam mode pengembangan atau dalam build profil produksi React v16.5+.
- Buka tab "Alat Pengembang" Chrome. Tab baru bernama "Profiler" akan tersedia, disediakan oleh React Developer Tools.
- Klik tombol "Rekam", dan lakukan tindakan yang ingin Anda buat profilnya. Idealnya, hentikan perekaman setelah Anda melakukan tindakan yang ingin Anda buat profilnya.
- Grafik (dikenal sebagai flamegraph) akan muncul dengan semua event handler dan komponen aplikasi React Anda.
Catatan : Lihat dokumentasi untuk informasi lebih lanjut.
Memoisasi Dengan React.memo()
React v16 dirilis dengan API tambahan, komponen tingkat tinggi yang disebut React.memo()
. Menurut dokumentasi, ini hanya ada sebagai pengoptimalan kinerja .
Namanya, " memo " berasal dari memoization, yang pada dasarnya adalah bentuk optimasi yang digunakan terutama untuk mempercepat kode dengan menyimpan hasil panggilan fungsi yang mahal dan mengembalikan hasil yang disimpan setiap kali fungsi mahal yang sama dipanggil lagi.
Memoisasi adalah teknik untuk mengeksekusi fungsi sekali, biasanya fungsi murni, dan kemudian menyimpan hasilnya dalam memori. Jika kita mencoba menjalankan fungsi itu lagi, dengan argumen yang sama seperti sebelumnya , itu hanya akan mengembalikan hasil yang disimpan sebelumnya dari eksekusi fungsi pertama, tanpa menjalankan fungsi lagi.
Memetakan deskripsi di atas ke ekosistem React, fungsi yang disebutkan adalah komponen React dan argumennya adalah props.
Perilaku default dari sebuah komponen yang dideklarasikan menggunakan React.memo()
adalah bahwa ia hanya dirender jika props dalam komponen telah berubah. Itu melakukan perbandingan alat peraga yang dangkal untuk memeriksa ini, tetapi opsi tersedia untuk menimpa ini.
React.memo()
meningkatkan kinerja aplikasi React dengan menghindari komponen rendering ulang yang propsnya tidak berubah atau saat rendering ulang tidak diperlukan.
Kode di bawah ini adalah sintaks dasar dari React.memo()
:
const MemoizedComponent = React.memo((props) => { // Component code goes in here })
Kapan Menggunakan React.memo()
- Komponen fungsional murni
Anda dapat menggunakanReact.memo()
jika komponen Anda berfungsi, diberikan props yang sama, dan selalu merender output yang sama. Anda juga dapat menggunakanReact.memo()
pada komponen non-fungsional murni dengan kait React. - Komponen sering dirender
Anda dapat menggunakanReact.memo()
untuk membungkus komponen yang sering dirender. - Komponen dirender ulang dengan alat peraga yang sama
GunakanReact.memo()
untuk membungkus komponen yang biasanya disediakan dengan props yang sama selama rendering ulang. - Elemen sedang hingga tinggi
Gunakan untuk komponen yang berisi elemen UI dalam jumlah sedang hingga tinggi untuk memeriksa kesetaraan props.
Catatan : Berhati-hatilah saat memoizing komponen yang menggunakan props sebagai callback. Pastikan untuk menggunakan instance fungsi panggilan balik yang sama di antara rendering. Ini karena komponen induk dapat memberikan contoh fungsi panggilan balik yang berbeda pada setiap render, yang akan menyebabkan proses memoisasi terhenti. Untuk memperbaikinya, pastikan bahwa komponen yang di-memo selalu menerima instance callback yang sama.
Mari kita lihat bagaimana kita dapat menggunakan memoisasi dalam situasi dunia nyata. Komponen fungsional di bawah ini, yang disebut “Photo”, menggunakan React.memo()
untuk mencegah rendering ulang.
export function Photo({ title, views }) { return ( <div> <div>Photo title: {title}</div> <div>Location: {location}</div> </div> ); } // memoize the component export const MemoizedPhoto = React.memo(Photo);
Kode di atas terdiri dari komponen fungsional yang menampilkan div yang berisi judul foto dan lokasi subjek dalam foto. Kami juga memoizing komponen dengan membuat fungsi baru dan menyebutnya MemoizedPhoto
. Memoisasi komponen foto akan mencegah komponen untuk dirender ulang selama props, title
, dan location
sama pada rendering berikutnya.
// On first render, React calls MemoizedPhoto function. <MemoizedPhoto title="Effiel Tower" location="Paris" /> // On next render, React does not call MemoizedPhoto function, // preventing rendering <MemoizedPhoto title="Effiel Tower" location="Paris" />
Di sini, React memanggil fungsi memo hanya sekali. Itu tidak akan membuat komponen di panggilan berikutnya selama props tetap sama.
Bundling dan Minifikasi
Dalam aplikasi satu halaman React, kita dapat menggabungkan dan mengecilkan semua kode JavaScript kita ke dalam satu file. Tidak apa-apa, selama aplikasi kita relatif kecil.
Seiring pertumbuhan aplikasi React kami, menggabungkan dan mengecilkan semua kode JavaScript kami menjadi satu file menjadi masalah, sulit untuk dipahami, dan membosankan. Ini juga akan mempengaruhi kinerja dan waktu pemuatan aplikasi React kami karena kami mengirim file JavaScript besar ke browser. Jadi, kami memerlukan beberapa proses untuk membantu kami membagi basis kode menjadi berbagai file dan mengirimkannya ke browser dalam interval yang diperlukan.
Dalam situasi seperti ini, kita dapat menggunakan beberapa bentuk bundler aset seperti Webpack, dan kemudian memanfaatkan fungsionalitas pemecahan kodenya untuk membagi aplikasi kita menjadi beberapa file.
Pemisahan kode disarankan dalam dokumentasi Webpack sebagai sarana untuk meningkatkan waktu pemuatan aplikasi. Itu juga disarankan dalam dokumentasi React untuk lazy-loading (hanya melayani hal-hal yang saat ini dibutuhkan oleh pengguna), yang secara dramatis dapat meningkatkan kinerja.
Webpack menyarankan tiga pendekatan umum untuk pemecahan kode:
- Titik masuk
Pisahkan kode secara manual menggunakan konfigurasi entri. - Pencegahan duplikasi
GunakanSplitChunksPlugin
untuk menghapus duplikat dan membagi potongan. - Impor dinamis
Pisahkan kode melalui panggilan fungsi sebaris dalam modul.
Manfaat Pemecahan Kode
- Pemisahan kode membantu dengan sumber cache browser dan dengan kode yang tidak sering berubah.
- Ini juga membantu browser mengunduh sumber daya secara paralel, yang mengurangi waktu pemuatan aplikasi secara keseluruhan.
- Ini memungkinkan kita untuk membagi kode menjadi potongan-potongan yang akan dimuat sesuai permintaan atau sesuai kebutuhan aplikasi.
- Itu membuat pengunduhan awal sumber daya pada render pertama relatif kecil, sehingga mengurangi waktu pemuatan aplikasi.
Struktur Data yang Tidak Dapat Diubah
Dokumentasi React berbicara tentang kekuatan tidak mengubah data. Data apa pun yang tidak dapat diubah tidak dapat diubah. Kekekalan adalah konsep yang harus dipahami oleh programmer React.
Nilai atau objek yang tidak dapat diubah tidak dapat diubah. Jadi, ketika ada pembaruan, nilai baru dibuat di memori, meninggalkan yang lama tidak tersentuh.
Kita dapat menggunakan struktur data yang tidak dapat diubah dan React.PureComponent
untuk secara otomatis memeriksa perubahan status yang kompleks. Misalnya, jika status dalam aplikasi Anda tidak dapat diubah, Anda sebenarnya dapat menyimpan semua objek status dalam satu penyimpanan dengan pustaka manajemen status seperti Redux, yang memungkinkan Anda untuk dengan mudah mengimplementasikan fungsi undo dan redo.
Jangan lupa bahwa kami tidak dapat mengubah data yang tidak dapat diubah setelah dibuat.
Manfaat Struktur Data yang Tidak Dapat Diubah
- Mereka tidak memiliki efek samping.
- Objek data yang tidak dapat diubah mudah dibuat, diuji, dan digunakan.
- Mereka membantu kami menulis logika yang dapat digunakan untuk memeriksa pembaruan status dengan cepat, tanpa harus memeriksa data berulang kali.
- Mereka membantu mencegah kopling temporal (sejenis kopling di mana kode bergantung pada urutan eksekusi).
Pustaka berikut membantu menyediakan kumpulan struktur data yang tidak dapat diubah:
- pembantu-kekekalan
Mutasi salinan data tanpa mengubah sumbernya. - tidak berubah.js
Pengumpulan data persisten yang tidak dapat diubah untuk JavaScript meningkatkan efisiensi dan kesederhanaan. - mulus-tidak berubah
Struktur data yang tidak dapat diubah untuk JavaScript menjadi kompatibel dengan array dan objek JavaScript normal. - Bereaksi-salin-tulis
Ini memberikan status yang tidak dapat diubah dengan API yang dapat diubah.
Metode Lain Untuk Meningkatkan Kinerja
Gunakan Pembuatan Produksi Sebelum Penerapan
Dokumentasi React menyarankan penggunaan build produksi yang diperkecil saat men-deploy aplikasi Anda.
Hindari Fungsi Anonim
Karena fungsi anonim tidak diberi pengidentifikasi (melalui const/let/var
), mereka tidak persisten setiap kali komponen pasti dirender lagi. Hal ini menyebabkan JavaScript mengalokasikan memori baru setiap kali komponen ini dirender ulang, alih-alih mengalokasikan satu bagian memori hanya sekali, seperti ketika fungsi bernama sedang digunakan.
import React from 'react'; // Don't do this. class Dont extends Component { render() { return ( <button onClick={() => console.log('Do not do this')}> Don't </button> ); } } // The better way class Do extends Component { handleClick = () => { console.log('This is OK'); } render() { return ( <button onClick={this.handleClick}> Do </button> ); } }
Kode di atas menunjukkan dua cara berbeda untuk membuat tombol melakukan tindakan saat klik. Blok kode pertama menggunakan fungsi anonim di prop onClick()
, dan ini akan memengaruhi kinerja. Blok kode kedua menggunakan fungsi bernama dalam fungsi onClick()
, yang merupakan cara yang benar dalam skenario ini.
Memasang Dan Melepas Komponen Seringkali Mahal
Menggunakan conditional atau tenaries untuk membuat komponen menghilang (yaitu meng-unmount-nya) tidak disarankan, karena komponen yang dihilangkan akan menyebabkan browser mengecat ulang dan mengatur ulang. Ini adalah proses yang mahal karena posisi dan geometri elemen HTML dalam dokumen harus dihitung ulang. Sebagai gantinya, kita dapat menggunakan properti opacity
dan visibility
CSS untuk menyembunyikan komponen. Dengan cara ini, komponen akan tetap berada di DOM tetapi tidak terlihat, tanpa biaya kinerja apa pun.
Virtualisasikan Daftar Panjang
Dokumentasi menyarankan bahwa jika Anda merender daftar dengan data dalam jumlah besar, Anda harus merender sebagian kecil data dalam daftar sekaligus dalam viewport yang terlihat. Kemudian, Anda dapat merender lebih banyak data saat daftar sedang digulir; karenanya, data hanya ditampilkan saat berada di viewport. Proses ini disebut "windowing". Dalam windowing, sebagian kecil baris dirender pada waktu tertentu. Ada perpustakaan populer untuk melakukan ini, dua di antaranya dikelola oleh Brian Vaughn:
- jendela reaksi
- reaksi-virtualisasi
Kesimpulan
Ada beberapa metode lain untuk meningkatkan kinerja aplikasi React Anda. Artikel ini telah membahas metode pengoptimalan kinerja yang paling penting dan efektif.
Saya harap Anda menikmati membaca tutorial ini. Anda dapat mempelajari lebih lanjut melalui sumber daya yang tercantum di bawah ini. Jika Anda memiliki pertanyaan, tinggalkan di bagian komentar di bawah. Saya akan dengan senang hati menjawabnya satu per satu.
Referensi Dan Sumber Daya Terkait
- “Mengoptimalkan Performa”, React Docs
- “Gunakan React.memo dengan Bijak”, Dmitri Pavlutin
- “Teknik Optimalisasi Kinerja dalam Bereaksi”, Niteesh Yadav
- “Kekekalan dalam Bereaksi: Tidak Ada yang Salah Dengan Objek yang Bermutasi”, Esteban Herrera
- “10 Cara Mengoptimalkan Kinerja Aplikasi React Anda”, Chidume Nnamdi
- “5 Tips untuk Meningkatkan Kinerja Aplikasi React Anda”, William Le