Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Vigorous perusal of large Redux stores leads to non-responsiveness and eventually OOM #599

@tailsu

Description

@tailsu

It always puzzled me why the redux store had a getState() method that returned the state, instead of simply having a state variable. Now I see that had it been implemented so, the react devtools would have died with even smaller stores and apps, with the entire content of the store serialized and transported once per every connected element through the element context.

I have an app with about a 20MB worth of data (when JSON-stringified) in the store and dozens or even hundreds of components in some pages picking various stuff from the store. Then I have a legion of HoCs that dutifully forward all props to the decorated components. Some of those properties come from the store of course, thus multiplying the number of times a set of values coming from the store gets serialized and passed to the devtools.

In essence, once my app loads, devtools needs about a minute to load, and then I have about a minute of time for perusal until the entire tab crashes with an out-of-memory.

So I modded the backend to call a user-supplied callback that can decide which props to really send to the frontend:

window.__REACT_DEVTOOLS_USER_MAPPERS__ = {
	mapState: state => state,
	mapProps: props => _.mapValues(props, (v, k) => {
		const state = store.getState();
		return state.hasOwnProperty(k) ? 'from Redux' : v;
	}),
	mapContext: context => context,
}

i.e., replace everything in props that is also a property of the state with the string 'from Redux'. Then I can take a look at the Redux Devtools to see the actual value. I thought that I needed to do the same for the context, but luckily, hey - getState().

The counterpart in backend/getData.js:

 var userMappers = window.__REACT_DEVTOOLS_USER_MAPPERS__;
...
    props = userMappers ? userMappers.mapProps(element._instance.props) : element._instance.props;
    state = userMappers ? userMappers.mapState(element._instance.state) : element._instance.state;
    context = userMappers ? userMappers.mapContext(element._instance.context) : element._instance.context;

And presto! React DevTools now connects at a fraction of the time that was necessary before and is actually usable.

Would you be willing to add this extension point, REACT_DEVTOOLS_USER_MAPPERS , to the kit? What are your thoughts on the issue? I don't submit a PR (yet), because I expect that a lot of things will likely change conceptually until the idea is ready for a PR (if at all). Until then, I'll be relying on this modded version to get my work done.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions