react flux/redux state should not contain calculated data - performance issues?

One of the core principles of flux is to have the app state at a bare minimum in the store. Everything that can be calculated based on other state data should not go into the store.

When I have a multiple filtered and sorted list the idea of having to calculate the final list from a bunch of base state info seems to be a performance issue. reselect claims to solve this problem to some degree, but what speaks against saving the final list as state too?

Answers


One issue with calculated lists is how they interact with 'shouldComponentUpdate'. If Redux re-performs the calculation every time anything changes in your flux state, then you end up with a different list object each time, and shouldComponentUpdate can't see that it hasn't actually changed (assuming it uses some kind of shallow comparison), so React will end up re-rendering all the components that depend on the list for every change. For a large amount of data, this may make the application somewhat unresponsive. However, if you employ infinite scrolling techniques (i.e. only render what is visible), and don't have a ludicrously large number of visible components (e.g. not a grid of 1000 tiny checkboxes), it's quite likely that there is no real performance problem with re-rendering for every change (and letting React do its diffing thing on the rendered JS tree).

That all said, reselect (more powerful approaches are possible if you use ImmutableJS or similar) will give you the optimization, by caching the result of the list calculation so React usually doesn't end up re-rendering if the list hasn't changed.

But avoiding multiple sources of truth, cache invalidation issues, etc. you get from keeping the calculated list in your application state is likely to be preferable. If you do this all over the place, then you end up with very complex logic to respond to changes - it will probably soon get unmanageable if you store derived state a lot and your application grows...


(I assume in your question that anything you call state actually is application state i.e. store/props, not the component State)

Keeping the list is as with any cache a trade-off between performance and

  • increased memory usage
  • potentially complex cache invalidation logic to determine when the list is stale

As a general rule, I would consider keeping any cache an optimization that should really be done last (don't do it, don't do it, do it, maybe)

In addition, if the component is not (re-)mounted on every render and thus receive props changes through componentWillReceiveProps() there is an opportunity to decide whether the list should be recalculated. If it is not needed, returning false in shouldComponentUpdate will keep the list as is. (the vDOM is the cache)

That being said there is one big factor in favor of a cache: avoiding I/O. If rebuilding the list involves I/O and it can be safely assumed that the list has not changed, a cache should be used.


Need Your Help

Check date with todays date

java android date

I have written some code to check two dates, a start date and an end date. If the end date is before the start date, it will give a prompt that says the end date is before start date.