Better performance with lottie animations using RLottie in react-native

Overview

🌈 react-native-rlottie

Features

  • ▶️ Uses rlottie to run lottie animations
  • 🌠 rlottie creates rasterized bitmaps for each frame of the animation (instead of using the platform's animation API to continuisly run the animation).
    • This also gives us the possibility to pre-render the animation into cache, so even complex animation can start and run in 60 FPS
  • Compatible with the new architecture (Fabric)
  • 🤖 Especially on android, using rlottie can be more performant than lottie-android (which is used by lottie-react-native):
    • 📉 Using less CPU and RAM
    • 🏃‍♂️ Puts less pressure on the UI/main Thread, ensuring 60 FPS even on low end devices
    • Read more in Performance Comparison

Usage

We try to be as close to the lottie-react-native implementation API, so you can use this library as drop-in replacement/complement.

So loading a local animation really is the same:

import React from 'react';
import {View} from 'react-native';
import RLottieView from 'react-native-rlottie';

const lottieAnim = require('./assets/icon_trophy.json');

const App = () => {
  return (
    <View>
      <RLottieView source={lottieAnim} style={styles.animation} />
    </View>
  );
};

const styles = StyleSheet.create({
  animation: {
    height: 700,
    width: 700,
  },
});

export default App;

Performance Comparison

All data for the comparison can be found here: https://docs.google.com/spreadsheets/d/1Akz2As7HSJ7n9kmpIMYG966GY4QybOkJth5nNewYZhs/edit?usp=sharing

We compared react-native-rlottie with lottie-react-native:

🤖 Android

react-native-rlottie vs lottie-react-native

Key observations

  • Running the animation consumes less CPU (-76%) and memory (-41%).
  • The animation runs fluently in 60 FPS, whereas lottie-android causes the FPS to drop.
    • This is due to the fact that the animation used for testing is a "complex" one, and running the animation with the platform's animated/art API is more expensive then to render the animation as bitmaps.

🍎 iOS

// TODO: Comparison for ios

Key observations

  • Running the animation with lottie-react-native adds CPU pressure. Using the example with an iPhone 7+ there is a ~10% CPU pressure during running the animation with lottie-rn, whereas with rlottie its 0%

Overall key points

  • Constantly running an animation with rlottie is in general more resource-saving, thus it can ensure more stable FPS, specially on low end devices.
  • HOWEVER, the first time you render the animation rlottie will use more resources than lottie-rn, as it needs to decode all frames for the first time. For large and complex animations this can be a severe factor. That's why, especially on iOS, its recommanded to pre-load an animation.
  • In general, you should check the performance implications for each animation you are using, and test yourself if you are getting better results with lottie-rn or rlottie.

Note: The performance results have been recorded with react-native-performance-stats.

How to test yourself

Click to expand:
  • Setup the example app on your machine
  • You might want to replace the animation to test with your own. Simply replace the file example/assets/icon_trophy.json
  • First, open the "Performance test: RLottie" screen in the example app and press start.
  • Wait ~20 seconds until an array is printed to your console output
  • Copy that data to a online service that convert JSON data in CSV: https://www.convertcsv.com/json-to-csv.htm
  • Copy the resulting table and paste the data in a copy of the benchmark google sheet named earlier
  • Repeat the same with the lottie-react-native screen

Installation

yarn add react-native-rlottie@alpha

npm i react-native-rlottie@alpha

iOS

Run pod install:

npx pod-install

Android

No additional steps for android are required, except when using the new react native architecture:

Click to expand for the instructions:

(Note: This setup is required to to the fact that the on android Autolinking doesn't work with the new architecture out of the box. This procedure will change in the future.)

  1. Open android/app/build.gradle file and update the file as it follows:
    defaultConfig {
        ...
        "PROJECT_BUILD_DIR=$buildDir",
        "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
    -   "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
    +   "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
    +   "NODE_MODULES_DIR=$rootDir/../node_modules/"
        cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
        cppFlags "-std=c++17"
  2. Open the android/app/src/main/jni/Android.mk file and update the file as it follows:
        # If you wish to add a custom TurboModule or Fabric component in your app you
        # will have to include the following autogenerated makefile.
        # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
    +
    +   # Includes the MK file for `react-native-rlottie`
    +   include $(NODE_MODULES_DIR)/react-native-rlottie/android/build/generated/source/codegen/jni/Android.mk
    +
        include $(CLEAR_VARS)
  3. In the same file above, go to the LOCAL_SHARED_LIBRARIES setting and add the following line:
        libreact_codegen_rncore \
    +   libreact_codegen_rlottieview \
        libreact_debug \
  4. Open the android/app/src/main/jni/MainComponentsRegistry.cpp file and update the file as it follows:
    1. Add the import for the RLottieView:
          #include <react/renderer/components/answersolver/ComponentDescriptors.h>
      +   #include <react/renderer/components/rlottieview/ComponentDescriptors.h>
          #include <react/renderer/components/rncore/ComponentDescriptors.h>
    2. Add the following check in the sharedProviderRegistry constructor:
          auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
      
          // Custom Fabric Components go here. You can register custom
          // components coming from your App or from 3rd party libraries here.
          //
          // providerRegistry->add(concreteComponentDescriptorProvider<
          //        AocViewerComponentDescriptor>());
      +   providerRegistry->add(concreteComponentDescriptorProvider<RLottieViewComponentDescriptor>());
      
          return providerRegistry;
      }

Supported After Effects Features

This has full feature parity with rlottie, so check their supported features here

Caveats

In our testing, on iOS, there is a blocking of the UI thread and it takes some time until the animation is ready (for our most complex animation its 2s!). On iOS we are still missing some of the optimziation that we have already on android such as async/threaded frame decoding on the fly. Once we add those features we believe the performance can be similar to android. However, more development/research is needed. If you are an iOS dev, we welcome you to take on the challenge and improve or provide wisdom 🙌

Development

We are open for and welcoming contribution of any kind!

To develop this library use the example/. Simply install the dependencies in the root dir with yarn and then install the dependencies in the example/.

As this library is compatible with the old and the new arch, it can be useful to check both versions during development.

🤖 Switching arch:

In example/android/gradle.properties you can simply toggle the newArchEnabled variable.

🍎 Switching arch:

Go into example/ios and run the following command setting RCT_NEW_ARCH_ENABLED to 1 or 0 depending on which arch you want to test:

cd ios && RCT_NEW_ARCH_ENABLED=1 pod install && cd ..

References / Used libraries / Thanks

You might also like...

This bare project template includes a minimal setup for using unimodules with React Native tvOS.

What This is a clone of expo's bare minimal template which includes a minimal setup for using unimodules with React Native. Additionally, this templat

Dec 25, 2022

React Native app demonstrating using xmtp-js to send a message

XMTP React Native Example This is a work in progress to demonstrate importing xmtp-js into a React Native app. The example currently generates a rando

Dec 20, 2022

In this course, we will learn how to build a complete full-stack web application using Spring boot as backend and React (React Hooks) as frontend

In this course, we will learn how to build a complete full-stack web application using Spring boot as backend and React (React Hooks) as frontend. We will use MySQL database to store and retrieve the data.

Dec 22, 2022

Customizable calendar with animations and ability to select a day, a week, a month or a custom range

Customizable calendar with animations and ability to select a day, a week, a month or a custom range

📅 RangeCalendarView A customizable, easy-to-use calendar with range selection Screenshots Getting started This library is available on Maven Central,

May 20, 2022

Photo live wallpaper with auto dark mode and power-efficient animations

Photo live wallpaper with auto dark mode and power-efficient animations

Pallax Android: Photo Live Wallpaper Pallax Android is an Android app that lets you convert your current static home screen background into a stunning

Dec 17, 2022

A React Native project starter with Typescript, a theme provider with hook to easy styling component, a folder architecture ready and some configs to keep a codebase clean.

React Native Boilerplate Folder structure : src ├── assets │   ├── audios │   ├── fonts │   ├── icons │   └── images ├── components │   ├── Layout.tsx

Sep 1, 2022

Lightweight React Native UI Components inspired on Vant

vant-react-native Install yarn add vant-react-native Or npm install vant-react-native Usage import React, { Component } from 'react'; import { View, T

Sep 29, 2022

Admob for React Native with powerful hooks and components

React Native Admob ⚠️ Please note, this package is under active development, which means it may be not stable to apply on production. Please use this

Jan 6, 2023

React Native wrapper around Indy SDK Java and Objective-C wrappers.

React Native Indy SDK React Native Indy SDK wrapper. Installation with npm: $ npm install indy-sdk-react-native --save with Yarn: $ yarn add indy-sdk-

Dec 5, 2022
Comments
Releases(v0.1.0-alpha.3)
Owner
Skill Nation
Amsterdam based tech studio, building bigger than life mobile gaming experiences.
Skill Nation
Sceneform React Native AR Component using ARCore and Google Filament as 3D engine. This the Sceneform Maintained Component for React Native

Discord Server Join us on Discord if you need a hand or just want to talk about Sceneform and AR. Features Remote and local assets Augmented Faces Clo

SceneView Open Community 42 Dec 17, 2022
With react-native-update-in-app library you can easily implement in-app updates in your React Native app using CDN or any other file server

React Native In-App update With react-native-update-in-app library you can easily implement in-app updates in your React Native app using CDN or any o

Nepein Andrey 7 Dec 21, 2022
Render After Effects animations natively on Android and iOS, Web, and React Native

Lottie for Android, iOS, React Native, Web, and Windows Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations expo

Airbnb 33.5k Jan 3, 2023
This is a Meme repo for fixed & Cleaned source of 'Better'Bungeecord but its not realy better code is trash!

#Fucking cleaned by CryCodes Disclaimer: Based of MD_5's Bungeecord (Fork of "BetterBungee") | I am not the owner of the code This repo is just for fu

Rooks 3 Jan 2, 2022
Android Library to create Lottie animation view dialog easily with a lot of customization

LottieDialog Android Library to create Lottie animation view dialog easily with a lot of customization Why you should use Lottie Dialog You have no li

Amr Hesham 39 Oct 7, 2022
React native wrapper for Jitsi Meet SDK Library that rely on the native view (Activity / ViewController)

react-native-jitsi-meet-sdk React native wrapper for Jitsi Meet SDK Library. This Library implements the Jitsi SDK with a native activity on the Andro

null 7 May 2, 2022
An awesome native wheel picker component for React Native.

⛏️ react-native-picky An awesome native wheel picker component for react-native. Features Supports multiple columns ✅ Supports looping ✅ Native Androi

null 28 Dec 4, 2022
Using turborepo & react-native

Turborepo starter with NPM This is an official starter turborepo. What's inside? This turborepo uses NPM as a package manager. It includes the followi

Renan Machado 5 Feb 16, 2022
This is a Food Delivery Mobile Application. Build Using React Native

Ax Food Delivery Service This is a Food Delivery Mobile Application build using ?????????? ???????????? ?? Installation Clone this repository git clon

Mindula Dilthushan Manamperi 13 Jul 14, 2022
This project is a simple messaging application made using React-Native framework, Gifted-Chat library and Firebase database

This project is a simple messaging application made using React-Native framework, Gifted-Chat library and Firebase database. The example that will be shown here focuses on the ability of two people to message each other in a chat room.

null 3 Jan 30, 2022