Frontend Development 10 min read

Using Lottie for Efficient Loading Animations: Overview, Implementation, and Performance Evaluation

This article examines the limitations of GIF loading animations, introduces Lottie as a cross‑platform solution, provides implementation details for web and React, presents performance comparisons with GIFs, and offers best‑practice guidelines for proper component cleanup.

ByteFE
ByteFE
ByteFE
Using Lottie for Efficient Loading Animations: Overview, Implementation, and Performance Evaluation

In the Feishu project, GIF animations were commonly used for loading indicators, but they suffer from large file size, fixed dimensions, lack of scalability, and limited control, prompting the search for a more efficient solution.

Lottie, an open‑source animation library from Airbnb, supports Android, iOS, Web, React Native, and Windows by exporting After Effects animations as JSON via the Bodymovin plugin, offering 100% visual fidelity.

Usage : The lottie-web library provides the most features, supporting SVG, Canvas, and HTML renderers (commonly SVG or Canvas). Example code to load an animation:

lottie.loadAnimation({
  container: element, // the DOM element that will contain the animation
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'data.json' // the path to the animation json
});

For React projects, react-lottie wraps lottie-web into a component. Example:

import React from 'react';
import Lottie from 'react-lottie';
import * as animationData from './pinjump.json';

export default class LottieControl extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isStopped: false, isPaused: false };
  }
  render() {
    const buttonStyle = { display: 'block', margin: '10px auto' };
    const defaultOptions = {
      loop: true,
      autoplay: true,
      animationData: animationData,
      rendererSettings: { preserveAspectRatio: 'xMidYMid slice' }
    };
    return (
this.setState({ isStopped: true })}>stop
this.setState({ isStopped: false })}>play
this.setState({ isPaused: !this.state.isPaused })}>pause
);
  }
}

The animation instance provides control methods such as play , stop , pause , goToAndStop , goToAndPlay , playSegments , setSpeed , setDirection , and destroy (see table below).

Name

Description

animation.play

Play the animation from the current frame.

stop

Stop playback and reset to frame 0.

pause

Pause at the current frame.

goToAndStop

Jump to a specific time/frame and stop.

goToAndPlay

Jump to a specific time/frame and play.

playSegments

Play specified frame segments, optionally forcing immediate playback.

setSpeed

Set playback speed (1 = normal).

setDirection

Set direction (1 = forward, -1 = reverse).

destroy

Destroy the animation and remove its DOM elements.

Event listeners include data_ready , complete , loopComplete , enterFrame , segmentStart , DOMLoaded , and destroy (see table below).

Name

Description

data_ready

Fired when the JSON animation is loaded.

complete

Fired when playback finishes (not on loop).

loopComplete

Fired at the end of each loop.

enterFrame

Fired on every frame entry.

segmentStart

Fired when a segment starts.

DOMLoaded

Fired after the animation DOM is added.

destroy

Fired when the animation is destroyed.

Performance Test : Comparing a GIF loading animation with a Lottie animation showed that the Lottie JSON file is only 4 KB (plus a 242 KB JS library) versus a 279 KB GIF. Lottie achieved a stable 59 fps, lower GPU usage (21.1 MB vs 28.6 MB), and comparable memory consumption.

方案

大小

FPS

CPU 占用率

GPU 占用

内存

Gif 动画

279KB

8‑60fps (多数 50fps, 波动大)

0%

28.6MB

94527

Lottie 动画

4KB (json) / 242.2KB (js)

20‑60fps (多数 59fps, 稳定)

0%

21.1MB

94825

The data indicates that Lottie provides smaller assets, higher and more stable frame rates, lower GPU usage, and similar memory consumption, making it a performant alternative to GIFs.

Precautions : Lottie components must be unmounted when not needed. In Feishu, lingering Lottie instances caused occasional CPU spikes (2‑5% vs idle 0.1‑0.2%) because requestAnimationFrame continued running. Proper cleanup can be done by conditionally rendering the component only when isLoading is true, as shown in the code examples.

// AppHome.js
// Proper unmount
{!!isLoading && (
)}

References:

Lottie – http://airbnb.io/lottie/#/

Lottie‑Android – https://github.com/airbnb/lottie-android

Lottie‑iOS – https://github.com/airbnb/lottie-ios

Lottie‑Web – https://github.com/airbnb/lottie-web

Lottie‑React‑Native – https://github.com/airbnb/lottie-react-native

React‑Lottie – https://github.com/chenqingspring/react-lottie

frontendPerformanceanimationLottiereact
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.