Use native solutions to achieve smooth animations and gesture-driven interface at 60FPS.
The following article is part of The Ultimate Guide to React Native Optimization and covers the sixth point of this guide: how to achieve animations at 60FPS.
Why is it important?
Nice and smooth animations are a crucial part of the success of your app. They improve the perception of them and make them more pleasant for your users. But, when done incorrectly, they can seriously damage your products by slowing them down. In this article, we describe some useful practices on how to achieve 60FPS animations in React Native with no harm to the speed of your app.
The previous parts of our guide discuss:
- Reducing the device’s battery usage with UI re-renders
- The best practices around using dedicated higher-ordered React Native components
- Picking external libraries
- Libraries optimized for mobile
Be sure to check them out. Now let’s move to the main topic.
Animate at 60FPS no matter what
Issue: JS-driven animations are occupying the bridge traffic and slow down the application.
Mobile users are used to smooth and well-designed interfaces that quickly respond to their interactions and provide prompt visual feedback. It is one of these things that is not really the case when it comes to web development but makes the difference on mobile. As a result, applications have to register a lot of animations in many places that will have to run while other work is happening.
As we know from the previous section, the amount of information that can be passed over through the bridge is limited. There’s no built-in priority queue as of now. In other words, it is on you to structure and design your application in a way that both the business logic and animations can function without any disruptions. This is different from the way we are used to perform animations. For example, on iOS, the built-in APIs offer unprecedented performance and are always scheduled with the appropriate priority. Long story short – we don’t have to worry much about ensuring they’re running at 60 FPS.
With React Native, this story is a bit different. If you do not think about your animations top-down beforehand and choose the right tools to tackle this challenge, you’re on the best way to run into dropped frames sooner or later.
Janky or slow animations affect the perception of the app, making it look slow and unfinished
In today’s world of a sea of applications, providing smooth and interactive UI might be one of your only ways to win over the customers that are looking to choose the app to go.
If your application fails to provide a responsive interface that works well with the user interactions (such as gestures), not only it may affect the new customers, but also decrease the ROI and user sentiment.
Mobile users like the interfaces that follow them along and that look top-notch and ensuring the animations are always running smoothly is a fundamental part that builds such experience.
Solution: If it’s possible, use native and correct animations
Enabling usage of native driver is the easiest way of improving your animations performance quickly. However, the subset of style props that can be used together with native driver is limited. You can use it with non-layout properties like transforms and opacity. It will not work with colors, height, and others. Those are enough to implement most of the animations in your app because you usually want to show/hide something or change its position.
Enabling native driver for opacity animation
For more complex use cases, you can use React Native Reanimated library. It’s API is compatible with basic Animated library and also introduce a set of more low-level functions to control your animations. What’s more important, it introduces the possibility to animate all possible style props with native driver. So animating height or color will no longer be an issue. However, transform and opacity animations still will be slightly faster since they are GPU accelerated. But regular users should not see any difference.
Gesture driven animations
The most desired effect that can be achieved with animations is being able to control animation with a gesture. For your customers, this is the most enjoyable part of the interface. It builds a strong sentiment and makes the app feel very smooth and responsive. Plain React Native is very limited when it comes to combining gestures with native driven animations. You can utilize ScrollView scroll events to build things like smooth collapsible header.
For more sophisticated use cases there is an awesome library – React Native Gesture Handler – which allows you to handle different gestures natively and interpolate those into animations. You can build a simple swipeable element by combining it with Animated. However it will still require JS callbacks, but there is a remedy for that!
The most powerful pair of tools for gesture-driven animations is the usage of Gesture Handler combined with Reanimated. Those were designed to work together and give the possibility to build complex gesture-driven animations that are fully calculated on the native side. The only limitation here is your imagination (and coding skills, since Reanimated low-level API is not so straightforward).
Read more: https://snack.expo.io/EM0KZfwJd
Low-level handling of gestures might not be a piece of cake, but fortunately, there are already 3rd party libraries that utilize mentioned tools and expose CallbackNodes. CallbackNode is nothing more than an Animated.Value, but it is derived from specific gesture behavior. Its value range is usually from 0 to 1, which follows the progress of the gesture. You can interpolate the values to animated elements on the screen. A great example of libraries that expose CallbackNode are reanimated-bottom-sheet and react-native-tab-view.
Read more: https://snack.expo.io/KFpkVKYB9
Giving your JS operations lower priority
Read more: https://snack.expo.io/Wv8u!mKwJ
Benefits: Enjoy smooth animations and gesture-driven interface at 60 FPS
There’s no one single right way of doing animations in React Native. The ecosystem is full of different libraries and approaches to handling interactions. The ideas suggested in this section are just recommendations to encourage you to not take the smooth interface for granted.
With such an approach, the application you create will be smoother and snappy. It will not only be pleasant for your users to use but also for you to debug and have fun with it while developing.
To sum up, nice and smooth animations can significantly influence the user experience and speed of your apps. If you would like to read more about the influence of animations on the user experience, check out this article.
In the next article, we will discuss how important it is to always run the latest React Native version to access the new features.
We are the official Facebook partners on React Native. We’ve been working on React Native projects for over 5 years, delivering high-quality solutions for our clients and contributing greatly to the React Native ecosystem. Our Open Source projects help thousands of developers to cope with their challenges and make their work easier every day.
Contact us if you need help with cross-platform or React Native development. We will be happy to provide a free consultation.