Redux: Kinerja Redux dengan Toko Besar dan pembaruan yang sering

Dibuat pada 28 Jan 2016  ·  18Komentar  ·  Sumber: reduxjs/redux

Ini pertanyaan / minta saran

Katakanlah Anda memiliki SPA yang cukup besar dengan banyak status karena ada banyak halaman, panel, sub panel, dan banyak hal.

Sekarang bayangkan Anda mendesain Aplikasi Anda menggunakan komposisi peredam (pada berbagai level) dan memiliki Store yang terorganisasi dengan baik sehingga membuat hidup Anda lebih mudah.

Sekarang bayangkan bahwa di salah satu panel Anda mendapatkan siaran langsung. Misalnya, katakanlah Anda memiliki daftar 100 item yang terdiri dari nilai bursa yang diperbarui masing-masing secara independen 1 kali per detik. (Harap abaikan masalah jaringan dan anggap nilainya dihasilkan secara acak).

Saya percaya React adalah cara yang harus dilakukan karena itu akan menjadi cerdas dan tidak akan merender ketika tidak diperlukan.

Tapi saya tidak yakin bagaimana membuatnya bekerja dengan Redux.

Sangat menyenangkan bahwa saya dapat menggunakan satu Toko dan mengambil semua nilai stok dan menyimpannya satu per satu memicu tindakan dan seterusnya dan memiliki Toko yang cukup bagus dengan semua info yang terorganisasi dengan sangat baik.

Tetapi karena saya mendapatkan pembaruan yang sangat sering, maka semua reduksi saya (yang akan banyak) harus dipanggil. Saya tahu bahwa panggilan akan sangat cepat karena sebagian besar waktu saya hanya akan menyalin pointer objek.

Bagaimanapun karena aplikasi saya menggunakan komposisi begitu banyak maka akan ada banyak panggilan fungsi. Ini bisa menjadi buruk khususnya pada perangkat seluler lama.

Saya sedang merancang satu aplikasi semacam itu dan saya tidak yakin bagaimana membuat Redux cocok di sana (jika mungkin). Mungkin Anda bisa memberikan beberapa saran berharga pada saat ini (saya baru saja mulai mengerjakannya). Apakah mungkin untuk menggunakan (entah bagaimana) Toko yang berbeda masing-masing hanya terhubung ke tindakan yang berbeda sehingga saya meminimalkan panggilan ke reduksi?

Ada ide?
Terima kasih

discussion

Komentar yang paling membantu

React Redux tidak menggunakan forceUpdate() sama sekali. Jauh lebih hati-hati :-)
Ya, itu tidak akan menyebabkan pembaruan yang tidak perlu.

Semua 18 komentar

Komentar ini dan seluruh diskusi dapat membantu: https://github.com/rackt/redux/issues/1287#issuecomment -176330134

Terima kasih @sompylasar. Pertanyaan saya agak berbeda.

Saya yakin bahwa nilai yang diperbarui adalah milik Store karena merupakan bagian mendasar dari Aplikasi.

Katakanlah kita memiliki toko seperti ini:

store: {
  subStore1: {
    subSubstore1: {}
    ...
    subSubstore10: {}
  },
subStore2: {
    subSubstore1: {}
    ...
    subSubstore10: {}
  }
...
subStore10: {
    subSubstore1: {}
    ...
    subSubstore10: {}
  }
}

(Saya harap Anda mendapatkan ide). Sebenarnya ini bisa lebih jauh lagi.

Semua substore sesuai dengan masalah yang sangat berbeda dari App dan subSubstore ditangani oleh reduksi mereka sendiri.

Kemudian saya mengirimkan tindakan yang saya tahu hanya akan memperbarui substore2:{substore6}.

Mengapa tidak menyalin pointer substore1, substore3, ...substore9 dan sekarang memanggil reduksi untuk subSubstore lainnya?

Apakah mungkin untuk memberi tahu combineReducers tindakan mana yang mungkin akan memicu status baru di reduksi anak mereka?

Atau mungkin saya harus mempertimbangkan untuk menggunakan Toko yang berbeda?

Ada saran?

Terima kasih!

Anda mungkin ingin melihat https://github.com/omnidan/redux-ignore.

Saya tidak tahu tentang redux-ignore dan itu pasti terlihat sangat menjanjikan!

Mungkin ini adalah cara yang mungkin untuk dilakukan ketika mengembangkan aplikasi yang sangat besar (SPA) yang menangani masalah ortogonal.

Terima kasih atas sarannya!

Tetapi karena saya mendapatkan pembaruan yang sangat sering, maka semua reduksi saya (yang akan banyak) harus dipanggil.

Biarkan saya membuat koreksi penting: Hanya ada satu fungsi peredam di toko Redux. Anda dapat memecah fungsi itu sesuka Anda, membuat tradeoff untuk kenyamanan, kecepatan, atau faktor lain tergantung pada kebutuhan Anda. combineReducers adalah cara umum untuk menangani ini, tetapi itu tidak diperlukan.

Satu ide yang berpotensi berkinerja yang saya miliki adalah memetakan type ke objek penangan, dikunci berdasarkan jenis. Inilah cara naif untuk melakukannya:

function buildReducer(handlers) {
  return function reducer(state = initialState, action) {
    return handlers[action.type](state, action);
  }
}

Maka Anda hanya akan menjalankan satu peredam per jenis. Tidak ada pemetaan tindakan 1:1 untuk reduksi, jadi Anda mungkin perlu mengurangi reduksi untuk setiap jenis, tetapi Anda masih akan menurunkan jumlah overhead.

Tentu saja, operasi DOM dan rendering React mungkin akan lebih lambat daripada beberapa JS biasa di aplikasi produksi Anda. Ditambah sebagian besar mesin JS akan memperlakukan reduksi Anda sebagai kode panas dan JIT mengkompilasinya ke kode asli, jadi saya tidak berharap itu akan menjadi lambat dalam praktiknya.

Anda juga dapat mendebounce render menggunakan redux-batched-subscribe , jadi jika Anda memiliki beberapa tindakan dalam durasi yang sangat singkat, itu hanya akan dirender sekali.

Lihat https://github.com/rackt/react-redux/issues/263 (ada tautan jsbin di sana)

Dalam kasus aplikasi besar yang menerima data yang didorong, haruskah struktur data hidup di pohon status?
Jika push terjadi setiap detik, kita akan berakhir dengan ribuan sejarah negara kan? Saya mengerti bahwa reduksi hanya mengubah sebagian kecil dari pohon.

Efek samping dari ini adalah layar devtools akan memiliki banyak elemen dom dan akan segera memperlambat browser. Itu datang ke titik di mana itu tidak dapat digunakan.

Apakah ini asumsi yang tepat?

@jorgecarmona Itu hanya memengaruhi Alat Dev, yang tidak digunakan dalam produksi. Alat Dev, seperti kebanyakan alat debugging atau pengembangan lainnya, tidak dirancang untuk berkinerja baik. Perhatian di sini adalah kinerja dunia nyata.

@timdorr Setuju.

Jadi kembali ke kinerja dunia nyata. Haruskah data yang mengalir ke aplikasi setiap detik diakumulasikan di pohon status? Apakah pendekatan ini berskala?

Jika Anda hanya menambahkan ke array dan tidak pernah menjadi jarang, maka seharusnya begitu. Anda mungkin mengalami beberapa kinerja O(n), tetapi Anda juga dapat menyelesaikannya melalui pos pemeriksaan dan memecah berbagai hal menjadi sub-array. Saya tidak berpikir itu akan menjadi hambatan Anda sebanyak pemeliharaan DOM frontend.

@timdorr Saya akan melakukan beberapa tes dengan rekomendasi tersebut.

Terima kasih telah meluangkan waktu untuk menjawab!

@gaearon @timdorr react-ignore membantu melewati beberapa subpohon peredam untuk beberapa tindakan sehingga kami memiliki pembaruan minimal di pohon status kami.
Tapi bagaimana dengan semua komponen yang sudah berlangganan status berubah.
Mereka akan diberi tahu meskipun status yang terkait dengan komponen belum diubah.

Apakah ada jauh untuk menghindarinya?

react-reducer membantu melewati beberapa subpohon peredam untuk beberapa tindakan sehingga kami memiliki pembaruan minimal di pohon status kami.

Tidak yakin apa yang Anda maksud. Saya tidak mengetahui proyek semacam itu. Apakah maksud Anda https://github.com/omnidan/redux-ignore?

Tapi bagaimana dengan semua komponen yang sudah berlangganan status berubah.

Gunakan https://github.com/reactjs/react-redux yang menangani ini. Ini memungkinkan Anda menentukan bagian tertentu dari status yang Anda pedulikan, dan berhati-hati untuk tidak memperbarui komponen React ketika bagian yang relevan tidak berubah.

Saya menutup utas ini karena diskusi asli telah tenang.

@gaearon

Gunakan https://github.com/reactjs/react-redux yang menangani ini. Ini memungkinkan Anda menentukan bagian tertentu dari status yang Anda pedulikan, dan berhati-hati untuk tidak memperbarui komponen React ketika bagian yang relevan tidak berubah.

Saya membaca yang berikut di doc.

mapStateToProps(state, [ownProps]): stateProps : Jika ditentukan, komponen akan berlangganan pembaruan toko Redux. Setiap kali diperbarui, mapStateToProps akan dipanggil. Hasilnya harus berupa objek biasa*, dan akan digabungkan ke dalam prop komponen

Hanya ingin memahami sepenuhnya apa yang terjadi di bawah tenda di sini, Jadi jika toko Redux diperbarui tetapi satu status komponen tertentu tidak berubah, Redux tidak akan memicu metode forceUpdate() untuk komponen itu.

Jika jawabannya ya, Anda telah membuat hari saya :)

React Redux tidak menggunakan forceUpdate() sama sekali. Jauh lebih hati-hati :-)
Ya, itu tidak akan menyebabkan pembaruan yang tidak perlu.

Lebih khusus: komponen pembungkus yang dihasilkan oleh fungsi connect() React-Redux melakukan beberapa pemeriksaan untuk mencoba meminimalkan berapa kali komponen Anda yang sebenarnya harus dirender ulang. Ini termasuk implementasi default shouldComponentUpdate , dan melakukan pemeriksaan kesetaraan dangkal pada props yang masuk ke komponen Anda (termasuk apa yang dikembalikan dari mapStateToProps ). Jadi ya, sebagai aturan umum, komponen yang terhubung hanya akan dirender ulang ketika nilai yang diekstraksi dari status telah berubah.

:+1: Manis.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

captbaritone picture captbaritone  ·  3Komentar

ms88privat picture ms88privat  ·  3Komentar

benoneal picture benoneal  ·  3Komentar

amorphius picture amorphius  ·  3Komentar

timdorr picture timdorr  ·  3Komentar