JS Thread drop in react-native app on redux action - javascript

I couldn't find too much information about my question after googling a lot. So maybe somebody has an answer.
So I use redux and redux-saga in my react-native app. I store a countdown timer state in the store because I have to persist the timer state.
The redux store state cca. over 15MB because the user has a lot of data while using the app. I recognized, that the JS Thread has a huge drop rate if an action is called and the store state has been changed. I tried with different sizes of data and I think the store size and the frame rate drop are in connection.
Does anybody have the same experience or any solution for this issue? I checked a lot of performance blog posts about that but nowhere could find a solution for this effect.
I am thinking about migrating to Zustand where I can apply separated little chunks for the global state and maybe it has better performance, but in the redux docs if I check the performance topic I can see a much bigger state like mine. So I don't have any idea at this point.
Otherway I checked my render state on these actions maybe it causes this but nothing renders unnecessarily.
So my conclusion is that when the new state is returned for some reason always generated a new large object which can happen slowly if the state size is over 15-20Mb.

Related

React Native JS frame drop when dispatching redux action

I'm developing an application using React Native + Redux and Redux Thunk. In one of actions, a large json data is fetched from our server and then dispatched to the store. When the dispatch happens, the JS thread frame rate drops from 60fps to 0 or 1 fps and so all touchables and buttons become not responsive and it's impossible to navigate through the app for a couple of seconds until the dispatch concludes and everything become normal again.
We've already made sure that only the components that needs this reducer data are re-rendering but the problem persists.
The data we are downloading is a json similar to a Map that may have hundreds or thousands of values.
Is there any way I can make React Native and Redux deal with this kind of data without dropping frames
"[...], there's nothing inherently slow or inefficient about how Redux is implemented. In fact, React Redux in particular is heavily optimized to cut down on unnecessary re-renders [...]"
Shouldn't be a problem for react-redux. Try to optimize your overall component structure:
Implement shouldComponentUpdate()-Method or PureComponents to get away from pointless rerenders. You could also consider designing a normalized redux state.
Split components in many individual pieces before connecting to the store.
Avoid overfetching and optimize lazy loading. You won't be able to display those data all at once.
This repository contains all articles treating the subject of 'Performance & Redux'. It's worth a visit ;)

React/Redux Large Real Time Data List Performance

Currently I have a large list of data (500 Rows) that at times many records can be updated a second. I'm using firebase's Real time Database. I am using React and Redux and basically whenever a record is changed, I fire a dispatch event to update the state in my app. When there are many records being updated it slows down and almost crashes the browser.
I've narrowed down my performance issues to it trying to dispatch 200+ actions at once. But since it is websockets/firebase I have no way of getting these updates in groups.
I am wondering if there is a library to use that will queue the dispatch requests and update the state one at a time, in order. Instead of trying to do it all at once.
Are these issues by any chance occurring in development with Redux dev tools also running?
Redux is fairly optimised to handle large data sets (particularly if you normalise your data structure). However, if you are dispatching a large number of actions and also have a large amount of data in your Redux store, using Redux dev tools can give a somewhat false impression of poor performance.
In a production build of your application there would only ever be one instance of your Redux state at a particular moment. Hence the first of the three Redux principles; single source of truth.
The difference whilst using Redux-dev tools in development however is that the dev tools keep a history of your actions and the state for each action dispatch you trigger. This subsequently can lead to large amounts of that data filling up your browser’s memory and thus giving the perception of poor performance.
You can also take a look at the Redux documentation on performance which has several further suggestions for how you can optimise your application.
If you would also like to show us how your data is structured in your reducer, or how you are handling your action dispatches, perhaps we can make further suggestions to improve your performance.

How can I tell Redux not to update React state yet?

I am currently dealing with a very large table of data. Some actions the user can take are quite complex - complex enough that I might end up dispatching a hundred actual actions to Redux, many of which will depend on the state being updated by previous actions, and causing a hundred state changes... which will result in the page seeming to lock up as numerous things in a very large table are rendered a hundred times, even though none of these updates will be individually meaningful to the user (or actively confusing)
Is there a way to delay Redux/React from seeing these changes - to say "okay, don't bother pestering React about this stuff, don't recalculate any props, don't do anything but throw this stuff through the reducers until it's done and I tell you it's done, and then return to normal behaviour" ?
I know I could set some React state property and then have a shouldUpdateComponent in each of my many components, but I was hoping there was a solution that involved less duplicate code scattered across dozens of files and perhaps even a bit more efficiency of avoiding calling the same exact function dozens of times per update.
Any suggestions?
Dan Abramov himself wrote on twitter an example of how to do this using batched actions and a higher order reducer.
https://twitter.com/dan_abramov/status/656074974533459968?lang=en
The gist of the idea is to wrap the actions you want to batch in another action, and define a higher order reducer (a reducer that returns another reducer, eg. redux-undo) that will apply all these actions when it handles the batched action update.

ReactJS local vs global state and implementing redux at a later time

So we are about two months in on a project. This is the first time I have ever managed code writers and not written the code myself. I've been reading their code for the last week. What was suppose to be a simple React app has turned into a spaghetti mess.
I understand: redux helps to manage global state. But should that mean that all buttons should map to a global "action?" This has seemed to create this entire mess of objects scattered throughout the entire app. I keep asking myself, why are we using global state for everything when local state could be used for 90% of the application. This is the kind of code that gives me heartburn:
let subitems = SidebarItems[state.type].sub_items;
Store.dispatch(SidebarSubItemHandler(item.action, subitems[0], null));
if(item.sub_items[subitems[0]].param) {
browserHistory.push(`${item.sub_items[subitems[0]].path}/${item.sub_items[subitems[0]].param}`);
} else {
browserHistory.push(item.sub_items[subitems[0]].path);
}
subItembuttons = Object.keys(this.props.subitems.sub_items).map(subitem => {
let subItem = this.props.subitems.sub_items[subitem];
return <li className={this.props.activeSubItem.action == subItem.action ? "bottom-bar-item active" : "bottom-bar-item"}
onClick={e => this.props.onClickSubItem(e, subItem)}
key={subItem.action} style={this.props.subitems.inlineStyles.mobileSubItemLI}>
{subItem.item}
</li>;
});
The application is littered with all kinds of objects like these that map to "action" objects. So at this point we are making the decision to scrap the entire project and restart from scratch, but without redux. Let's try to do as much as possible using local state only. When it comes time, and we need global state for something, ONLY implement it for that something, not every single action in the app. Does this make sense?
So I guess my question is: If we develop an app using local state and just fundamental React, will we be creating un-reversable problems that would prevent us from implementing redux on a per item basis?
Quoting from the relevant Redux FAQ entry at http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-only-redux-state:
Using local component state is fine. As a developer, it is your job to determine what kinds of state make up your application, and where each piece of state should live. Find a balance that works for you, and go with it.
Some common rules of thumb for determing what kind of data should be put into Redux:
Do other parts of the application care about this data?
Do you need to be able to create further derived data based on this original data?
Is the same data being used to drive multiple components?
Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)?
Per your specific question: if you use the "container component" pattern fairly consistently, it should be relatively straightforward to swap those "plain React" containers for Redux-connected containers down the line. See https://github.com/markerikson/react-redux-links/blob/master/react-component-patterns.md#component-categories for articles on the "container/presentational component" pattern.
Two other thoughts. First, I recently co-authored an article that discusses why you might want to use Redux in a React application.
Second: yeah, that code looks kinda ugly. I'm hoping those are at least three different snippets from different parts of the codebase, rather than one snippet, but that's rather hard to read. The repeated use of "sub_items" and "subitems" seems like a bit of a red flag, readability-wise.
It also doesn't look like it's following good Redux practices. For example, idiomatic Redux code almost never references the store directly. Instead, references to dispatch and getState are available via middleware, and thus can be used in action creators via redux-thunk and redux-saga. Connected components can also access dispatch.
Overall: you are absolutely welcome to use as much or as little Redux as you want, and as much or as little local component state as you want. I think the larger issue, though, is how well your team actually understands Redux, and how they're trying to use it.

How to deal with component state with redux?

I have been using vanilla React for a while, and have now decided to take a closer look at Redux for a new project I am doing.
At first I got the impression that all user activity should result in actions, with one of the main reasons being that you would be able to reconstruct any application state by just playing back the appropriate actions.
The problem with this, however, is that you put a lot of stuff in the store that in reality does not feel like application state. Stuff like "If I focus on this input, the label turns green" does not seem like state fitted for being represented in the application state of an application that is potentially composed by hundreds of components. These things make total sense with the typical todo-tutorial, but it can be difficult to see how it will turn out in a more complex scenario.
Then I read some more, and found that the general opinion, backed by creator Dan Abramov, is that you should usually combine local component state with the application state (store). "Whatever seems least awkward" seemed to be the rule of thumb for where to store state.
On one hand this makes total sense: The things that are really application state, and are relevant for multiple components should be in the store, while the strictly presentational details that only concerns one single component should be handled using normal react state. On the other hand this approach confuses me a bit, because of what I wrote in the beginning: Isn't a big part of the point with redux that you avoid having the state distributed among the components, and that you are able to recreate state by just storing the actions?
I hope someone can shed some light on this concern, because it has been bothering me, and it is something I think I should get a solid opinion about before trying to build something complex with redux.
What state you put where is entirely up to you. Sometimes it may make sense to put everything in Redux, sometimes it may make sense to keep stuff in a component. I recently saw some good rules-of-thumb:
Do other parts of the application care about that data?
Do you need to be able to derive further data from that data?
Is the same data being used to drive multiple components/features?
Is there value to you, to being able to restore the state to a given point in time (ie: time travel / debugging)?
Do you want to cache the data, ie: reload it from state if it's already there instead of requesting it again?
(Credit to https://www.reddit.com/r/reactjs/comments/4w04to/when_using_redux_should_all_asynchronous_actions/d63u4o8 for that list.)
Also see the Redux FAQ on this topic: http://redux.js.org/docs/FAQ.html#organizing-state-only-redux-state .

Categories

Resources