I am using Redux and React to build a web application. My application is an analytics application that renders a lot of data. I am running into performance issues when my store becomes large.
What is the preferred way of avoiding performance issues with large data in redux?
Application Structure
My app is structured in a way where I have settings
(small json), results
(large json), and calculate(settings)
. Calculate is deterministic and idempotent. My app renders settings metadata and the results in graphs, tables, etc.
Because calculate is deterministic and idempotent, I know results will not change when settings does not change. When settings do change my results may change. In other words, I'm comfortable relying on only settings to determine if I need to update my UI.
Redux Behavior & Potential Solutions
My application is slow when I include results inside my store:
let settings = { foo: "bar" };
let results = calculate(settings);
Object.assign({}, state, { settings: settings, results: results });
//deterministic and idempotent
function calculate(settings) {
return /*large json*/;
}
My application is fast when I reference but don't include results inside my store:
let settings = { foo: "bar" };
let results = calculate(settings);
Object.assign({}, state, { settings: settings, results: () => results });
//deterministic and idempotent
function calculate(settings) {
return /*large json*/;
}
I know redux advises against storing functions, so an alternative is to save a reference using a string...something like:
let settings = { foo: "bar" };
let calculationId = uuid(); //could also be a hash of settings if I want to avoid some false positive UI re-rendering
let results = calculate(settings);
setResults(calculationId, results);
Object.assign({}, state, { settings: settings, calculationId: calculationId });
//deterministic and idempotent
function calculate(settings) {
return /*large json*/;
}
let fakeStore = { calculationId: null, results: null };
function setResults(calculationId, results) {
fakeStore. calculationId = calculationId;
fakeStore.results = results;
}
function getResults(calculationId) {
if(fakeStore.calculationId === calculationId) {
return fakeStore.results;
}
throw new Error("Invalid data access");
}
render() {
let calculationId = this.props.calculationId;
let results = getResults(calculationId);
}
Keeping large data outside of the store is tenable, but it seems like there may be better ways react supports this use case.
Using redux 3.7.1, react 15.4.2, react-redux 4.4.8