你可能处于两种情况之一。要么你有一个设计师给你一个 Lottie JSON 并要求你,“我们能在今天把它放进应用程序吗?”,要么你已经连接了它并注意到动画在开发中工作,但一旦进入真实设备、启动时间和发布构建,它就开始感觉很昂贵。
Lottie React Native 的地方很有趣。基本示例很容易。生产就绪的实现并不是那么容易的。通常情况下,差异取决于你如何安装它、如何控制播放和是否将动画文件视为无害资产还是将其视为你的性能预算的一部分。
目录
- Lottie 为 React Native 应用程序而言是必不可少的
- 设置 Lottie 开发环境
- 显示您的第一个 Lottie 动画
- 掌握 Lottie 动画控制
- 生产应用程序的性能调优
- 常见 Lottie 问题的故障排除
为什么 Lottie 对 React Native 应用程序至关重要
如果你曾经尝试用React Native手动重建一个完美的产品动画,你已经知道了痛苦。小动作细节变成了一个堆积的时间逻辑、插值和平台特性。动画可能看起来很接近,但“接近”通常不是设计师交付的东西。
Lottie改变了工作流程。Airbnb在2016年开源了Lottie,并且这一发布改变了移动动画,让设计师直接交付动画,而不是迫使工程师重建它们帧帧。 在某些企业环境中,这一转变降低了移动应用开发成本, 根据Airbnb的Lottie概述,降低了40%。设计和工程停止争夺同一目标 Lottie React Native的关键优势不仅仅是“JSON中的漂亮动画”。它是分离关注点。设计师在After Effects中工作,并且使用Bodymovin导出。开发者使用原生支持的播放来渲染输出,而不是将运动翻译成自定义__CAPGO_KEEP_0__。.
这很重要,因为动画工作有一个习惯会扩散。一个单独的庆祝状态动画可以触及设计审查、产品审查、Android行为、iOS行为、可访问性和启动性能。Lottie缩小了这个表面面积。
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时,动画是产品体验的一部分,而不是仅仅需要一个简单的透明度或translate转换时。 在产品体验中使用Lottie时,动画是产品体验的一部分,而不是仅仅需要一个简单的透明度或translate转换时。
There’s also a user experience angle. Motion gives feedback, confirms actions, and makes loading states feel less dead. If your team is thinking seriously about polish, retention, or trust in the interface, animation is part of that conversation. The broader 应用体验讨论的更广泛层面 通常会结束在同一个地方:快速反馈击败静态屏幕
Lottie 在哪里最合适
Lottie React Native tends to work best for:
- 品牌微互动 例如点赞、保存、勾选和购买成功状态
- 引导图 需要感觉自定义而不需要发送视频
- 加载和空白状态 静态 UI 感觉不完整的场景
- 功能教育 当产品需要运动效果而不想嵌入 GIF 或 MP4 时
它并不能解决所有动画问题。对于基本的屏幕过渡,React Native 自身的动画工具往往更简单。对于非常大的或高度交互的运动系统,JSON 格式会成为一个权衡,而不是赢得。
设置您的 Lottie 开发环境
安装路径取决于一个决定: Expo 管理工作流或裸 React Native不要混淆两种思维模型。最常见的设置问题发生在开发者在 Expo 内使用裸工作流程指南,或者假设 Expo 抽象了每个本机细节。

在安装之前选择工作流
如果您的应用程序在 Expo 中运行并且您希望获得最快的设置,请在知道您需要自定义本机工作时保持在 Expo 路径上。如果您处于裸应用程序中,或者您已经依赖于需要直接控制的本机模块,请将其安装为正常的本机依赖项,并立即验证 iOS 和 Android 构建。
许多团队低估了当保持设置与项目类型一致时调试变得多么容易。这也是为什么许多团队在构建自定义本机集成时早早转向 Expo 开发客户端工作流 而不是等待应用程序变得更难改变。
Expo管理的设置
对于Expo管理的应用程序,保持简单。
-
安装包
npx expo install lottie-react-native -
重启Metro
npx expo start -c -
在设备或模拟器上验证 从本地JSON文件开始,并首先渲染一个非常小的动画。不要同时调试一个大资产和一个新安装。
在Expo中,几个实际的注意事项很重要:
- 优先使用本地文件: 远程动画调试会在您只想证明库正常工作时添加网络噪音。
- 尽早测试发布行为: 开发模式可能会隐藏与时序和性能相关的问题。
- 监控资产路径: JSON 文件位置不当是最常见的“渲染无效”原因。
Expo 是快速实现“它可以工作”的捷径,但这并不意味着它是快速实现“它可以扩展”的捷径。
裸露的 React Native 设置
在裸露的项目中,立即安装并验证原生依赖项。
-
安装包
npm install lottie-react-native -
安装 iOS pods
cd ios && pod install && cd .. -
重建应用
npx react-native run-ios或
npx react-native run-android
许多快速启动指南都忽略了这一点:安装后,进行一次完整的原生重建,然后才能确定某些东西是有问题的。热重载无法修复原生依赖项未正确编译到应用中的问题。
裸露工作流程可以节省时间
在继续之前,请使用以下简短的检查清单:
| 检查 | Why it matters |
|---|---|
| 安装后重新构建 | 原生模块需要重新编译 |
运行 pod install |
没有它,iOS就不靠谱 |
| 首先使用一个简单的本地JSON | 隔离安装问题和资源问题 |
| 尽早测试两种平台 | Android和iOS可能因为不同的原因失败 |
如果包安装正常,但第一个动画没有显示出来,那通常不是安装问题。通常是资源路径、组件大小或播放配置的问题。
显示第一个Lottie动画
第一个工作的动画应该很无聊。使用本地文件。固定大小。自动播放。循环可选。不要从条件播放、远程JSON或复杂的层次结构导出开始。

添加一个本地动画文件
如果你还没有一个资产文件夹,创建一个:
assets/
animations/
success.json
保持名称简单。避免使用空格、奇怪的标点符号和多层次的文件夹。您希望 require() 路径保持明显。
如果您正在使用 Lottie 为启动屏幕或首次启动后进行手动操作,想想在启动路径中放置一个大动画之前。尤其是当您还在调整 React Native 启动屏幕行为.
Render it with 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()path: 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 错误出现在动画需要响应状态时。自动播放很容易。 “当用户喜欢一个项目时播放这个段落,反转时当他们不喜欢它时,且在组件重新渲染时不要卡顿” 是问题的关键所在。

使用属性时播放
对于非交互式播放,属性已经足够了。
<LottieView
source={require('../assets/animations/loading.json')}
autoPlay
loop
speed={1}
/>
适合此风格的场景包括:
- 加载指示器
- 被动的引导图示
- 装饰性空白状态
它是声明性的和可读的。组件加载,播放开始,React 还在控制。如果动画逻辑可以完全通过属性描述,保持它在那里。
一个更复杂的声明性案例是 progress在动画帧中绑定另一个值时,效果很好,尤其是当动画反映某个外部进度源时,但对于一次性触发事件来说,这种方式不太方便。
动画效果的快速可视比较,之后我们会讨论refs:
当状态驱动动画时,使用refs
当用户点击、切换或完成某个动作时,refs通常是一个更安全的选择。现实世界的数据表明 使用混合框架的开发者中有68%的人由于在hooks中处理refs不当而导致动画触发失败在 useEffect hooks,这就是为什么在 animation.current.play() __CAPGO_KEEP_0__-关注的讨论中提到过的失败触发问题 Capacitor-focused discussion of failed triggers.
可靠的喜欢和不喜欢模式
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避免不必要的重新渲染。 - 组件避免了自动播放的冲突: 你不希望挂载行为与用户触发的行为发生冲突。
值得避免的常见错误:
-
在ref存在之前触发
如果animationRef.current如果为 null,播放将不会发生。保护它。 -
使用
autoPlay与命令式控件
选择一个默认的播放器所有者。 -
驱动
useEffect
效果很有用,但在 UI 动作中,它们经常会引入时间问题而不是去除它们。
如果一个动画响应一个点击,首先在点击处理器内部触发它。只有
useEffect当真实数据源位于该交互之外时才使用。
生产应用程序的性能调优
Lottie React Native 是一种看起来很轻量级的库,直到团队开始将大型 JSON 文件塞入应用程序包中并Wondering 为什么启动时间回归。动画本身并不是问题。传递策略才是。

团队会陷入困境
最容易犯的错误是将每个动画直接打包到 JavaScript 中并在启动时全部加载。 根据关于错误地将 Lottie JSON 导出 的指南过载 JS 包含 Lottie JSON 等资产会在中档设备上
增加启动时间
- 40% 或更多
- 将它们移动到原生资产中进行按需加载是关键优化。
- 这与许多团队在实践中看到的结果一致。
- 问题不是单个小型成功动画。
- 而是堆积:
引导动画
优化的第一步是什么
首先优化导出本身。导出动画时存在的复杂性会在解析、内存和渲染稳定性方面带来后果。不要接受设计师导出原样。
使用此生产清单:
- 在交付前压缩 JSON 文件: 较小的文件更容易加载,启动时也更不容易膨胀。
- 将非关键动画从 JS 包中移除: 保持启动 code 聚焦于应用程序立即需要的内容。
- 按需加载动画: 在屏幕或动作需要时渲染。
- 审计旧设备行为: 现代模拟器可以隐藏昂贵的播放。
- 避免使用大型 Lottie 文件作为启动装饰: 如果它对首次交互不是至关重要的,那么它就不应该与应用启动竞争。
对于严肃地进行移动性能工作的团队来说, AppLighter的移动性能指南 是一个有用的参考读物,因为它将动画决策置于应用启动、渲染和框架权衡的更大背景下。
一个艰难的真相: 一个延迟首次交互的美丽动画通常是一个产品bug,而不是一个设计胜利。
您还应该超越React Native的孤立思考。混合堆栈的团队会遇到类似的资产加载问题,而更广泛的 Capacitor应用的动画性能指南 也适用于Lottie决策。
本地文件与远程交付
本地文件是可预测的。它们在离线状态下工作,消除了网络变异性,并且更容易测试。它们也容易过度打包。
远程交付使二进制文件更瘦,但现在您的动画有可用性、缓存和fallback问题。这种权衡对于非关键动作是可接受的,但对于主要的UX状态,如购买确认或身份验证成功,它就很有风险。
一个实用的分离方案效果很好:
| 资产类型 | 更好的默认值 |
|---|---|
| 核心交互动画 | 本地、优化、不超载 |
| 偶尔的促销动画 | 远程fallback |
| 启动路径动画 | 仅当绝对必要时本地 |
| 少用特性说明 | 按需加载 |
如果您只从本节中应用一个规则,请使用这个: 对 Lottie JSON 文件视为性能敏感资产,而不是无害的装饰.
常见 Lottie 问题的故障排除
当 Lottie 出现问题时,通常是因为普通原因。 路径错误。 缺少尺寸。 错误的引用时间。 overweight JSON。 debug 最快的方法是减少变量。
在 Android 上,动画无法渲染
首先确认 JSON 文件解析正确。 然后为组件指定明确的尺寸。
<LottieView
source={require('../assets/animations/success.json')}
autoPlay
style={{ width: 200, height: 200 }}
/>
如果仍然无法解决问题,请切换到一个已知的良好动画。 这可以告诉你问题是否出在文件上还是设置上。
在旧设备上,播放动画时出现卡顿
这通常指向资产,而不是组件 API。
尝试以下修复方法:
- 减少动画复杂度: 如果源文件很重,请要求导出一个更轻的版本。
- 延迟加载: 不要与初始屏幕工作竞争。
- 测试压缩版本: 如果压缩文件表现更好,那么你找到了瓶颈。
- 移除多个同时显示的Lottie视图: 屏幕上有多个动画可能太多了。
ref为null或play无效
通常null refs意味着触发器在mount之前触发,或者组件被条件删除。
if (animationRef.current) {
animationRef.current.play();
}
使用 useRef,并且不要不必要地重建动画组件。如果你在本地构建中反复出现奇怪的bug,清除过时的缓存可能会有所帮助。一个简单的 Yarn缓存清理程序 有时足以在开发期间移除误导性的资产行为。
动画在不同屏幕尺寸上看起来不正确
不要让动画定义布局。将其放入一个容器中并有意地设置其大小。
- 使用固定边界的图标和反应
- 使用更大的插图的比例感知包装器
- 在没有检查导出意图组合的情况下不检查拉伸到全宽
大多数“Lottie 是破损”的报告最终都是布局问题、资产问题或时间问题。该库经常做的是你要求它做的。
如果您需要一个最终的调试快捷方式,请删除每个高级属性,渲染一个本地动画在一个居中的视图中,然后从那里逐步构建。这种方法比凝视一个繁忙的生产屏幕更快地隔离问题。
Capgo 帮助团队将 JavaScript、资产和配置修复推送到 Capacitor 应用程序,而无需等待商店审查。如果您维护一个混合应用程序并需要一种更安全的方式来推送更新、处理阶段性发布和快速恢复前端问题, Capgo 值得一看。