I'm building a new app with React Native and Expo. The main function of this app is to generate plans for user. The generating algorithm will take estimated around 300-500 seconds to execute. (It contains maximum 2,100,000 times of random generating.)
Currently I am facing two problems:
Q1. during testing, this piece of code is put in the App.js - App class - render function directly. however, it seems that if the execution time exceeds 32 seconds the app will just fail to render and stay no response forever.
So the question is:
1.1 what's the reason of the maximum 32 seconds otherwise no response?
1.2 are there better ways to do testing?
Current testing method:
export default class App extends React.Component {
componentDidMount() {
if (__DEV__) {
Reactotron.connect();
Reactotron.log('hello rendering world');
}
}
render() {
//test
generatePlan(store.getState(), 0);
return (
<Provider store={store}>
<AppContainer />
</Provider>
);
}
}
Q2. at the end, it's not possible to let user keep dazing such a long time after click an "generating" button. So ideally, this long executing task should be running in the background with limited resource (both memory and calculating), so that the user can do other things during waiting without too much being influenced(like a virus scanning task, once it finishes, pops up a message, etc.)
So the question here is:
how to implement this?
What I have tried:
For Q1: currently I have no idea about the reason and even can't figure out the accurate key words to search. (I tried search "react native long execution time", "no response", etc in google, react native github issue, Expo forum, but no luck.)
currently my idea to do testing is to execute each part separately and manually store the result of each part. Then do the final part with the stored result of each part.
For Q2: There is a library "react-native-background-task":
"This library allows the scheduling of a single periodic task, which executes when the app is in the background or closed, no more frequently than every 15 minutes. Network, AsyncStorage etc can be used (anything except UI), so perfect for things like a background data sync for offline support."
But there are two questions about this potential solution:
a. how to run task in the background when the app is open?
b. how to limit the calculating resource used by this task? (as the task can be executed slowly, but it shouldn't occupy too much calculating resource if the user is still using the mobile phone.)
@Heysem Katibi thanks a lot for shedding light on this.
below is my discovery and experience along the way to solve this problem.
Solutions in details:
react native Javascript worker: react-native-threads (itself or with hamsters.js to further speed up).
react-native-threads will spawn new react native JavaScript processes for CPU intensive work outside of the main UI JavaScript process.
hamsters.js is a Javascript Multithreading & Parallel Execution Library, can further speed up the execution while it needs a worker library with React Native (ex: react-native-threads).
requestAnimationFrame: Break code into pieces and execute in each frame.
See Intensive JavaScript. This probably can work, however as this article shows, the performance will be worse than worker.
move to native code:
In any cases, moving code to native will probably boost up the execution.
move to server side: use remote server to do the heavy job and the mobile side just request the result. Also, this can work with above solutions (considering using the same language to write the code and reuse on both mobile and server side).
By thankful original poster.
P.S: I just discovered that it's very difficult to encrypt javascript code in React Native project. Thus it's not advised to put any sensitive code in javascript and even in front end.
Well, I don't think there is one definite answer to your question, But here is what I think:
render() method. This method is called frequently whenever a piece of the state is updated or the component is re-rendered. So it should be as light as possible and should only contain the returned components, Also to avoid any unexpected behaviors the render() method should be a pure method related to its component's props and state.requestAnimationFrame for every piece, For example, if your algorithm generates a random number then does some calculation on it and repeats this process for 2 million times, You'll need to requestAnimationFrame for every calculation, store the current result somewhere and request another frame for the next calculation.
Good Luck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With