An important aspect of any quality mobile app is the fluidity of the user interface. Animations are used to provide a rich user experience, and any jank or jitter can negatively affect this. Animations will likely be used for all kinds of interactions, from changing between views, to reacting to a user's touch interaction on a component. The second most important factor for high-quality animations is to make sure that they do not block the JavaScript thread. To keep animations fluid and not interrupt UI interactions, the render loop has to render each frame in 16.67 ms, so that 60 FPS can be achieved.
In this recipe, we will take a look at several techniques for improving the performance of animations in a React Native mobile app. These techniques focus in particular on preventing JavaScript execution from interrupting the main thread.
This article is taken from the book React Native Cookbook, Second Edition by Dan Ward. In this book, you will improve your React Native mobile development skills and learn how to transition from web development to mobile development.
For this post, we'll assume that you have a React Native app that has some animations defined.
The output in Android will look something like the following screenshot:
componentWillMount() { this.setState({ fadeAnimimation: new Animated.Value(0) }); }
componentDidMount() { Animated.timing(this.state.fadeAnimimation, { toValue: 1, useNativeDriver: true }).start(); }
componentWillMount() { this.setState({ isAnimationDone: false }); } componentWillUpdate() { LayoutAnimation.easeInAndOut(); }
componentDidMount() { InteractionManager.runAfterInteractions(() => { this.setState({ isAnimationDone: true }); }) } render() { if (!this.state.isAnimationDone) { return this.renderPlaceholder(); } return this.renderMainScene(); }
The tips in this recipe focus on the simple goal of preventing the JavaScript thread from locking. The moment our JavaScript thread begins to drop frames (lock), we lose the ability to interact with our application, even if it's for a fraction of a second. It may seem inconsequential, but the effect is felt immediately by a savvy user. The focus of the tips in this post is to offload animations onto the GPU. When the animation is running on the main thread (the native layer, rendered by the GPU), the user can interact with the app freely without stuttering, hanging, jank, or jitters.
Here's a quick reference for where useNativeDriver is usable:
Function | iOS | Android |
style, value, propertys | √ | √ |
decay | √ | |
timing | √ | √ |
spring | √ | |
add | √ | √ |
multiply | √ | √ |
modulo | √ | |
diffClamp | √ | √ |
interpoloate | √ | √ |
event | √ | |
division | √ | √ |
transform | √ | √ |
If you liked this post, support the author by reading the book React Native Cookbook, Second Edition for enhancing your React Native mobile development skills.
React Native 0.59 is now out with React Hooks, updated JavaScriptCore, and more!
React Native community announce March updates, post sharing the roadmap for Q4
How to create a native mobile app with React Native [Tutorial]