Animations in React Native. How to achieve great performance and tips — 1x04

Tasos Maroudas
Mar 15, 2018 · 5 min read

This story is part of a series where I am sharing my experiences on React Native: how I approached and worked with RN Components, APIs, external packages and all sorts of issues. I hope that this series of posts will prove useful to the React Native community and provide helpful insights.

Why are animations important?

Animations are important in order to create an optimal user experience, especially in the mobile world. App users have been exposed to a lot of them already, and have become familiar with their usability and beauty. And since they have hands-on experience with them, they expect them as a given in every single app they download. As per the React Native animations documentation:

Objects in motion have momentum.

Animations allow you to convey physically believable motion in your interface.

Image 1: Animations are awesome!

Animation systems in React Native

React Native provides two complementary animation systems: Animated and LayoutAnimation. These are 2 different APIs with a different usability and purpose.

My personal feeling is that Animated is more widely used from developers, probably because it provides more control — and it also comes with better documentation.

In this article I assume that you are familiar with Animated API and I will blog on how to achieve the best performance out of it, alongside some other practical tips.

Animated API tips: Performance and more

In order to create an animation you can find very good documentation and “how to start” examples in React Native animations documentation.

To achieve great performance you always need to make use of the configuration prop useNativeDriver (with value set to true). For example, in order to animate the rotation of an image our timing function would look like that:

This config prop is very very important because that way, RN sends the animation to be executed at the native realm directly passing through the bridge only once, thus achieving the best possible performance. If you are not familiar with the JavaScript/native realms and their bridge, you can get more insights in this post by @TalKol.

Now, according to RN documentation useNativeDriver prop cannot be used for all animation types:

Not everything you can do with Animated is currently supported in Native Animated. The main limitation is that you can only animate non-layout properties, things like transform and opacity will work but flexbox and position properties won’t.

There is a way though to overcome this, if you are composing animations. For instance let’s take an example from the Math Warriors Android app where we change the size of our logo image when the user clicks the start game button.

Image 2: Logo size increase animation when start game button is clicked in Math Warriors

What we do at this point is that we change the width and height of the logo simultaneously and these properties do not support use of the animated driver property. Their parallel execution though does support it as shown below:

RN does not support loop animations out of the box, so we had to find a way. A 2nd example from Math Warriors game, which is actually the extension of our previous example, is the following: as soon as the user presses the start game button, the logo increases its size and also starts moving up and down in a loop and until the app matches the player with an opponent.

Image 3: Logo movement animation in a loop when start game is clicked in Math Warriors

We performed this by creating a JavaScript interval id. The catch here is that in order to avoid app glitches and waiting time, you need to execute the actual animation twice: the 1st one and all the others that will follow inside a loop (JavaScript interval).

For the users of styled components you can convert any of the 4 animatable components (View, Text, Image, ScrollView) to a styled component like that:

In order to understand how your animation will behave you need to test it on a real device. Emulators cannot provide this kind of feedback. On the contrary, your animation may run flawlessly in an emulator environment and be sticky on a real device. Only the real device test can reveal if the animation shows at 60 FPS or less, which is when we experience slow breaking animations.

What do you think?

What do you think about these animations’ tips? How do you make your animations work for you? Offer your perspective and ideas in the comments section below.

Do you have a specific subject that you would like me to cover? If I have worked with it, I will be more than happy to share my perspective.

If you enjoyed this article, feel free to hit that clap button 👏 to help others find it.

Hi there, I’m Tasos; a software engineer that loves web and currently works a lot with React Native and React. I’m the co-founder of Coded Lines software agency where we undertake end-to-end mobile & web projects with emphasis to in-app marketing. If it sounds what you are looking for, please contact me here: Thanks for stopping by :)

Building With React Native

Technical posts about React Native. What issues we encountered while developing Math Warriors Android game and how we solved them.

Tasos Maroudas

Written by

Front End / Mobile Engineer currently working with React Native, React & TypeScript 😃 Part time blogger. Co-Founder of Coded Lines Ltd

Building With React Native

Technical posts about React Native. What issues we encountered while developing Math Warriors Android game and how we solved them.