React + Redux: scalability & performance
Vitaliy Redko
Ezetech
THE PROBLEM
We mostly get nested data structure
from backend like this:
PROBLEM REASONS
● Data prejoining on MongoDB document level
● Data aggregation on MongoDB query level
THE PROBLEM
BUT it leads us to the headache while
dealing with nested data structures in
Redux actions or React components
THE PROBLEM
And we start (to do stupid things):
● to write FAT ACTIONS;
or / and
● to POLLUTE REACT COMPONENTS with heavy
data processing calls
THE PROBLEM
PERFORMANCE LEAKS:
● data processing in React components on
each render()
● nested data manipulation in actions
SOLUTION?
SOLUTION
● Store normalization
● Composable selectors
STORE NORMALIZATION
STORE NORMALIZATION
When STORE is NORMALIZED
that gives us the possibility to write
thin actions & pure reducers
with no logic for nested data processing.
COMPOSABLE SELECTORS
SELECTORS are the functions we use to fetch data from
store as props for React component:
SELECTORS SCHEMA
NORMALIZED
STORE
SELECTORS
REACT
COMPONENTS
ACTIONS
COMPOSABLE SELECTORS
Don’t treat selectors as getters for store slices
Treat selectors as props composition layer
COMPOSABLE SELECTORS
BENEFITS:
● We save less data in store
● We get rid of data processing in React
COMPOSABLE SELECTORS
reselect killer features:
● selectors memoization
● selectors composition (nesting)
COMPOSABLE SELECTORS: RESELECT
COMPOSABLE SELECTORS
COMPOSABLE SELECTORS
MULTIPLE COMPONENTS (!)
MULTIPLE COMPONENTS (!)
To prevent memoization lose with multiple components:
1. Wrap your mapStateToProps():
MULTIPLE COMPONENTS (!)
To prevent memoization lose with multiple components:
2. Wrap your selectors:
TESTING: UPDATE EVERY (WS)
nested reducers flat store & composable selectors
20,7% faster
94.1% faster
TESTING: PAGE RELOAD
nested reducers flat store & composable selectors
16.2% faster
33.2% slover
TESTING: ALL CONTENT UPDATE
nested reducers flat store & composable selectors
48.8% faster
62.1% faster
REACT PERFORMANCE TIPS
Don’t use this.state within setState()
REACT PERFORMANCE TIPS
Get rid of unnecessary rerendering
(shouldComponentUpdate):
REACT PERFORMANCE TIPS
Get rid of unnecessary rerendering
(lodash memoization):
REACT PERFORMANCE TIPS
Get rid of unnecessary rerendering
(fast-memoize memoization):
REACT PERFORMANCE TIPS
Get rid of unnecessary rerendering
(don’t create props within render() - use defaultProps):
SUMMARY TIPS
SELECTORS
● Place your selectors close to reducers
● Wrap selectors and mapStateToProps()
into function to use with multiple
component instances
● Reuse selectors as input to high order
selectors
SUMMARY TIPS
STORE
● Normalize your store
● Split your store on simplest slices
● Separate your filters as store slices
● Don’t put derived data into store
BENEFITS
● Scalability
● Performance gain
● Ability to use derived data from selectors
and save less data in store
TOOLS
STORE NORMALIZATION:
● normalizr
https://github.com/paularmstrong
/normalizr
● redux-orm
COMPOSABLE SELECTORS
● reselect
https://github.com/reactjs/reselect
● fast-memoize
● ramda
● redux-orm
ABOUT ME
Vitaliy Redko
email: vitaliy.redko@gmail.com

Виталий Редько "React + Redux: performance & scalability"