跳过主要内容
移动端 指南

Lottie React Native

我们的完整指南教您如何使用 Lottie React Native。涵盖 Expo & bare 工作流程、动画控制、性能调优和 2026 年最佳实践。

马丁·多纳迪厄

马丁·多纳迪厄

内容营销

Lottie React Native

您可能处于两种情况之一。要么您有一个设计师向您提供一个 Lottie JSON 并要求您,“我们可以将其添加到应用程序中吗?”要么您已经将其连接起来并注意到动画在开发中正常工作,但一旦进入真实设备、启动时间和发布构建,它们就开始变得昂贵。

Lottie React Native 的有趣之处在于。基本示例很容易。生产就绪的实现并不是那么简单。通常,差异取决于您如何安装它、如何控制播放以及您是否将动画文件视为无害资产还是将其视为您的性能预算的一部分。

目录

Why Lottie Is Essential for React Native Apps

如果你曾经尝试在 React Native 中手动重建一个精致的产品动画,你已经知道了痛苦。小动作细节变成了一个堆积的时间逻辑、插值和平台特性。动画看起来很接近,但‘接近’通常不是设计师交付的。

Lottie 改变了工作流程。Airbnb 在 2016 年开源了 Lottie,随后该发布改变了移动动画,让设计师可以直接交付动画,而不用迫使工程师重建它们帧帧。 在某些企业环境中,这种转变降低了移动应用开发成本,据 Airbnb 的 Lottie 概述称,降低了 40%。 根据Airbnb 的 Lottie 概述 设计和工程停止争夺同一战场.

Lottie React Native 的一个关键优势不仅仅是‘JSON 中的漂亮动画。’它是关注点分离。设计师在 After Effects 中工作并使用 Bodymovin 导出。开发者使用原生支持的播放来渲染输出,而不是将运动转换为自定义 __CAPGO_KEEP_0__。

A key benefit of Lottie React Native isn’t just “pretty animations in JSON.” It’s the separation of concerns. Designers work in After Effects and export with Bodymovin. Developers render the output with native-backed playback instead of translating motion into custom code.

实用规则:

使用 Lottie 时,动画是产品体验的一部分,而不是仅仅需要一个简单的透明度或 translate 转换时。 动画在屏幕尺寸跨度下看起来不正确

除了用户体验角度外,还有一个动画的重要性。动画可以给用户反馈,确认操作,并让加载状态感觉更活跃。如果您的团队正在认真考虑界面上的细节、留存率或信任,动画就是其中一个重要的方面。更广泛的 应用程序用户体验讨论 通常会以相同的结论结束:快速反馈比静态屏幕更重要。

Lottie在哪里最有效

Lottie React Native通常在以下场景中表现最佳:

  • 品牌微互动 例如点赞、保存、勾选和购买成功状态
  • 引导图示 需要感觉自定义但不需要发送视频的图示
  • 加载和空白状态 在静态UI感觉不完整时
  • 功能教育 当产品需要动画效果而不需要嵌入 GIF 或 MP4 时

它并不能解决所有动画问题。对于基本的屏幕转换,React Native 自身的动画工具往往更简单。对于非常大的或高度交互的动画系统,JSON 格式会成为一个权衡,而不是赢得。这种权衡在生产环境中变得更加重要,这也是大多数教程停留在早期的原因。

设置 Lottie 开发环境

安装路径取决于一个决定: Expo 管理工作流或裸 React Native不要混淆两种思维模式。大多数设置问题发生在开发者在 Expo 内部遵循裸工作流指南,或者假设 Expo 抽象了所有本机细节时。

一个流程图,展示了在 Expo 和裸 React Native 项目中设置 Lottie 动画的步骤。

在安装之前选择工作流

如果您的应用程序位于 Expo 并且您希望获得最快的设置,请在 Expo 路径上保持,除非您知道需要自定义本机工作。 如果您处于裸应用程序中,或者您已经依赖本机模块,需要直接控制,安装它作为正常的本机依赖项,并立即验证 iOS 和 Android 构建。

许多团队低估了当保持设置与项目类型一致时,调试变得多么容易。这也是为什么许多团队在构建自定义本机集成时,早早转向 Expo 开发客户端工作流的原因。 在 Expo 开发客户端工作流中设置 Lottie 动画 在 Expo 开发客户端工作流中设置 Lottie 动画

Expo管理的设置

对于Expo管理的应用程序,保持简单。

  1. 安装包

    npx expo install lottie-react-native
  2. 重启Metro

    npx expo start -c
  3. 在设备或模拟器上验证 从本地JSON文件开始,并首先渲染一个非常小的动画。不要同时调试一个大资产和一个新安装。

几个实用的注意事项在Expo中很重要:

  • 首先使用本地文件: 远程动画调试会在你只想证明库正常工作时添加网络噪音。
  • 早期测试发布行为: 开发模式可能会隐藏与时间和性能相关的问题。
  • 监视资产路径: 最常见的‘它渲染了什么’原因之一就是 JSON 文件丢失。

Expo 是快速实现‘它工作’的捷径,但这并不意味着它是实现‘它可扩展’的捷径。

裸露的 React Native 设置

裸露项目中,立即安装并验证原生依赖项。

  1. 安装包

    npm install lottie-react-native
  2. 安装 iOS pods

    cd ios && pod install && cd ..
  3. 重建应用

    npx react-native run-ios

    或者

    npx react-native run-android

在选择替代方案时,以下问题值得考虑:

在选择替代方案时,以下问题值得考虑:

在选择替代方案时,以下问题值得考虑:

在选择替代方案时,以下问题值得考虑: 为什么它很重要
安装后重新构建 原生模块需要重新编译
运行 pod install 没有它,iOS就不靠谱
首先使用一个简单的本地JSON 将安装问题与资产问题隔离
尽早测试两种平台 Android和iOS可能会因为不同的原因失败

如果包安装成功,但你的第一条动画没有显示出来,那通常不是安装问题。通常是资产路径、组件大小或播放配置的问题。

显示你的第一个Lottie动画

第一个工作的动画应该很无聊。使用本地文件。固定大小。自动播放。循环可选。不要从条件播放、远程JSON或复杂的层次结构导出开始。

A modern developer workspace with a laptop displaying code and a monitor showing a mobile animation app.

添加一个本地动画文件

如果您尚未创建一个,请创建一个资产文件夹:

assets/
  animations/
    success.json

保持名称简单。避免使用空格、奇怪的标点符号和多层次的文件夹。您希望 require() 路径保持清晰。

如果您正在使用 Lottie 为启动屏幕或启动后的手动传递创建一个初始品牌加载屏幕,请在启动路径中放置一个大型动画时要小心。尤其是当您还在调整 React Native 启动屏幕行为时 使用 LottieView 渲染它.

创建一个专门的组件而不是直接将其放入一个大屏幕文件中:

它证明了库正确渲染

import React from 'react';
import { View, StyleSheet } from 'react-native';
import LottieView from 'lottie-react-native';

export function SuccessAnimation() {
  return (
    <View style={styles.container}>
      <LottieView
        source={require('../assets/animations/success.json')}
        autoPlay
        loop={false}
        style={styles.animation}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  animation: {
    width: 220,
    height: 220,
  },
});

它证明了资产路径正确解析

  • 它证明了组件正确工作
  • 它证明了组件正确渲染
  • 它为您提供一个单独的位置来调整播放和大小

如果您跳过基础知识,立即会出现几个问题:

  • 没有宽度或高度: 动画可以存在但不可见。
  • 错误 require() 路径: Metro找不到文件。
  • 无效导出: 某些 JSON 文件从技术上讲是有效的,但包含的功能在移动设备上不按预期工作。

保持第一次渲染本地和确定性的。您正在测试集成,而不是架构。

更好的首屏测试

将组件放置在一个简单的屏幕上,背景中性:

import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { SuccessAnimation } from './src/SuccessAnimation';

export default function App() {
  return (
    <SafeAreaView style={styles.screen}>
      <SuccessAnimation />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
  },
});

如果在 iOS 和 Android 模拟器中都能正常工作,你已经跨过了第一个真正的障碍。从那里,下一步不是添加更多的动画。它是学习何时使用声明性属性和何时使用 refs 进行直接控制。

掌握 Lottie 动画控制

大多数 Lottie React Native 错误出现在动画需要响应状态时。自动播放很容易。"当用户喜欢一个项目时播放这个段落,反转时不喜欢,且在组件重新渲染时不卡顿",才是麻烦的地方。

Lottie 中的声明性和命令式动画控制方法的比较表格,突出了它们的具体用途。

使用属性时播放时简单

对于非交互式播放,属性就足够了。

<LottieView
  source={require('../assets/animations/loading.json')}
  autoPlay
  loop
  speed={1}
/>

这种风格适用于:

  • 加载指示器
  • 被动的引导图
  • 装饰性的空白状态

它是声明性的和可读的。组件挂载,播放开始,React 还在掌控。如果动画逻辑可以完全用属性描述,保持它就好。

一个更复杂的声明性案例是 progress,绑定动画帧到另一个值。这种方法在运动反映外部进度源时很好用,但在触发事件时不太方便。

快速比较前,让我们移动到refs:

使用refs时,状态驱动动画

当用户点击、切换或完成某个动作时,refs通常是更安全的工具。现实世界的数据显示 使用混合框架的开发者中有68%的人报告由于在 useEffect 钩子中处理refs不当而导致的动画触发失败,这就是为什么建立在 animation.current.play() 的可靠模式很重要的原因,正如本 Capacitor-专注于失败触发的讨论中所述的那样.

这个问题不仅限于混合应用。它也出现在普通的React Native中,尤其是在开发者重复创建refs、在挂载之前触发播放或将动画调用与不稳定效果绑定时。

import React, { useRef, useState } from 'react';
import { Pressable } from 'react-native';
import LottieView from 'lottie-react-native';

export function LikeButton() {
  const animationRef = useRef<LottieView>(null);
  const [liked, setLiked] = useState(false);

  const onPress = () => {
    if (!animationRef.current) return;

    if (liked) {
      animationRef.current.play(60, 0);
    } else {
      animationRef.current.play(0, 60);
    }

    setLiked(!liked);
  };

  return (
    <Pressable onPress={onPress}>
      <LottieView
        ref={animationRef}
        source={require('../assets/animations/like.json')}
        loop={false}
        autoPlay={false}
        style={{ width: 96, height: 96 }}
      />
    </Pressable>
  );
}

可靠的喜欢和不喜欢模式

这个模式在生产环境中比直接调用更可靠 play() inside useEffect 每次状态改变时都会发生。

为什么它有效:

  • 事件拥有动画触发器: 按压事件是开始播放的稳定时刻。
  • ref保持局部和持久: useRef 避免不必要的重新渲染。
  • 组件避免了自动播放的冲突: 您不希望挂载行为与用户触发的行为发生冲突。

值得避免的常见错误:

  1. 在ref存在之前触发
    如果 animationRef.current 如果为 null,播放将不会发生。保护它。

  2. 使用 autoPlay 使用命令式控制
    选择一个播放的默认拥有者

  3. 将所有内容驱动到 useEffect
    效果很有用,但在 UI 动作中,它们经常会引入时间问题而不是去掉它们。

如果动画响应一个点击,首先在点击处理器内部触发它。只有在真实数据源位于该交互之外时才使用 useEffect 生产应用的性能调优

Lottie React Native 是一种看起来很轻量的库,直到团队开始将大型 JSON 文件塞入应用程序包中并Wondering 为什么启动时间回归。动画本身并不是问题。交付策略才是。

一个详细的 infographic,展示了 Lottie 性能调优的三个关键优势:减小包大小、提高帧率和降低内存使用率。

团队会陷入困境

Where teams get into trouble

直接将每个动画打包到 JavaScript 中并在启动时全部加载是最容易犯的错误,根据 本指南关于错误地将 Lottie JSON 发送到客户端的说明,将 Lottie JSON 等资产打包到 JS 包中会在中档设备上增加启动时间,达到 40% 或更多,将它们移动到原生资产中进行按需加载是关键优化

这与许多团队在实践中看到的结果一致。问题不是单个小型成功动画,而是积累:

  • 启动动画
  • 加载器状态
  • 电子商务反应
  • 品牌空白屏幕
  • 区域文件和其他打包密集资产

如果您的应用程序已经存在启动预算问题,Lottie 文件会迅速使其恶化

优化的第一步是什么

首先优化导出本身。导出的动画如果不清晰,会带来解析、内存和渲染稳定性的复杂性。不要接受设计师导出的所有内容不做任何修改。

使用以下生产检查表:

  • 在运输之前压缩 JSON: 更小的文件更容易加载,启动时也不会导致膨胀。
  • 将非关键动画从 JS 包中移除: 保持启动 code 聚焦于应用程序立即需要的内容。
  • 按需加载动画: 在屏幕或动作需要时渲染。
  • 检查旧设备的行为: 现代模拟器可以隐藏昂贵的播放。
  • 避免使用大型 Lottie 文件作为启动装饰: 如果它对首次交互不是至关重要的,那么它就不应该与应用启动竞争。

对于严肃地进行移动性能工作的团队来说 移动性能指南 是AppLighter的有用伴侣阅读,因为它将动画决策置于应用启动、渲染和框架权衡的更大背景中。

一个艰难的真相: 延迟首次交互的美丽动画通常是一个产品bug,而不是一个设计胜利。

您还应该超越React Native的孤立思考。混合堆栈的团队会遇到类似的资产加载问题,而更广泛的 Capacitor 动画性能指南

与Lottie决策也很相似。

本地文件与远程传递

本地文件是可预测的。它们可以在离线状态下工作,去除网络变异性,并且更容易测试。它们也容易过度打包。

A实践中的分离效果很好:

资产类型 更好的默认值
核心交互动画 本地、优化、不超载
偶尔的促销动画 远程有fallback
启动路径动画 仅当绝对必要时才使用本地
少用特性插图 按需加载

如果您只从本节中应用一个规则,请使用这个: 优化 Lottie JSON 文件的性能,避免它们被视为无害的装饰.

解决常见的 Lottie 问题

当 Lottie 出现问题时,通常是因为一些普通的问题:路径错误、尺寸缺失、引用时间错误、JSON 文件过大。快速调试的方法是减少变量。

Android 设备上动画无法渲染

首先确认 JSON 文件可以解析,然后为组件设置明确的尺寸。

<LottieView
  source={require('../assets/animations/success.json')}
  autoPlay
  style={{ width: 200, height: 200 }}
/>

如果仍然无法解决问题,请尝试使用一个已知的良好动画。这样可以确定问题出在文件还是设置上。

旧设备上的播放效果不佳

This usually points to the asset, not the component API.

尝试以下解决方案:

  • 减少动画复杂度: 如果源文件很重,请要求导出一个更轻的版本。
  • 延迟加载: 不要与初始屏幕工作竞争。
  • 测试压缩版本: 如果压缩文件表现得更好,你就找到了瓶颈。
  • 移除多个同时显示的Lottie视图: 在一个屏幕上显示多个动画可能太多了。

ref为null或play无效

通常null refs意味着触发器在mount之前触发,或者组件被条件删除。

if (animationRef.current) {
  animationRef.current.play();
}

保持ref稳定使用 useRef,并且不要不必要地重建动画组件。如果你在本地构建中反复出现奇怪的问题,清除陈旧的缓存可以有所帮助。一个简单的 Yarn缓存清理程序 有时足以移除开发期间的误导性资产行为。

动画在不同屏幕尺寸上看起来不正确

不要让动画定义布局。将其放入一个容器中并有意地设置大小。

  • 使用固定边界的图标和反应
  • 使用比例感知的包装器来处理更大的插图
  • 避免在没有检查导出意图的组合的情况下拉伸到全宽

大多数“Lottie出现问题”的报告最终都是布局问题、资产问题或时间问题。库通常是做了你要求它做的事情。

如果你需要一个最终的调试快捷方式,移除所有高级属性,渲染一个本地动画在一个居中的视图中,然后从那里逐步构建。这种方法比盯着一个繁忙的生产屏幕更快地隔离问题。


Capgo 帮助团队将 JavaScript、资产和配置修复推送到 Capacitor 应用程序,而不必等待商店审查。如果你维护一个混合应用并需要一种更安全的方式来推送更新、处理阶段性发布和快速恢复前端问题 Capgo 值得一看。

实时更新 Capacitor 应用

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

当 web 层 bug 活跃时,通过 __CAPGO_KEEP_0__ 发布修复,而不是等待几天的 app 商店审批。用户在后台接收更新,而原生变化仍在正常审批路径中。

context: Capgo 营销网站. 角色: 支持描述段落或元描述。 见于: 组件 GetStarted.astro. 保留 Capgo 产品/品牌和开发者术语的原始形式。

来自 Martin 的人性化支持

Capgo gives you the best insights you need to create a truly professional mobile app.