framer-motion vs react-transition-group vs react-native-reanimated vs react-spring vs lottie-react-native vs react-native-animatable
React 与 React Native 动画库的技术选型指南
framer-motionreact-transition-groupreact-native-reanimatedreact-springlottie-react-nativereact-native-animatable类似的npm包:

React 与 React Native 动画库的技术选型指南

framer-motionlottie-react-nativereact-native-animatablereact-native-reanimatedreact-springreact-transition-group 都是用于在 React 或 React Native 应用中实现动画效果的流行库,但它们的设计目标、性能特征和适用场景差异显著。framer-motionreact-spring 主要面向 Web 端,提供声明式、物理驱动的动画能力;react-transition-group 专注于基于状态变化的进入/离开过渡;而 react-native-reanimatedlottie-react-nativereact-native-animatable 则专为 React Native 设计,分别针对高性能原生动画、Lottie JSON 动画集成和简单内置动画封装。这些库在渲染线程、API 风格、性能开销和跨平台支持方面存在关键区别,开发者需根据项目平台、动画复杂度和性能要求进行权衡。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
framer-motion30,657,21831,0784.6 MB2155 天前MIT
react-transition-group24,065,22410,258244 kB256-BSD-3-Clause
react-native-reanimated2,968,51710,6863.91 MB3438 天前MIT
react-spring897,61029,0508.36 kB1345 个月前MIT
lottie-react-native873,53817,134290 kB1213 天前Apache-2.0
react-native-animatable555,7199,95559.8 kB1702 年前MIT

React 与 React Native 动画库深度技术对比

在现代前端开发中,动画不仅是视觉点缀,更是提升用户体验的关键手段。然而,面对 framer-motionlottie-react-nativereact-native-animatablereact-native-reanimatedreact-springreact-transition-group 这些主流动画库,开发者常陷入“选哪个”的困境。本文从真实工程视角出发,深入剖析它们的核心机制、适用边界与性能特征,助你做出精准技术决策。

🧩 核心定位与平台支持

首先明确一点:这些库并非完全可互换。它们分为 Web 专用React Native 专用跨平台 三类。

  • Web 专用framer-motionreact-spring(默认配置)、react-transition-group
  • React Native 专用lottie-react-nativereact-native-animatablereact-native-reanimated
  • 跨平台react-spring(通过 @react-spring/native 支持 RN)

⚠️ 注意:react-native-animatable 自 2019 年起已无实质性更新,官方仓库标记为“不再积极维护”,强烈不建议在新项目中使用

🖥️ Web 端动画:声明式 vs 物理模型 vs 状态过渡

基础进入/离开动画:react-transition-group

如果你只需要在组件挂载/卸载时添加简单过渡(如淡入淡出),react-transition-group 是最轻量的选择。它不处理复杂动画逻辑,而是帮你管理 CSS 类名切换。

// react-transition-group
import { CSSTransition } from 'react-transition-group';

function Fade({ in: inProp }) {
  return (
    <CSSTransition in={inProp} timeout={300} classNames="fade">
      <div>Hello</div>
    </CSSTransition>
  );
}

/* 对应 CSS */
.fade-enter { opacity: 0; }
.fade-enter-active { opacity: 1; transition: opacity 300ms; }

声明式高阶动画:framer-motion

framer-motion 以极简 API 实现复杂交互动画,尤其擅长布局动画和手势集成。

// framer-motion
import { motion } from 'framer-motion';

<motion.div
  animate={{ x: 100, rotate: 360 }}
  transition={{ type: 'spring', stiffness: 300 }}
/>

// 布局动画示例
<motion.div layout>
  {isOpen && <motion.div layoutId="panel">Content</motion.div>}
</motion.div>

物理驱动动画:react-spring

react-spring 基于弹簧物理模型,适合需要自然弹性效果的场景(如拖拽回弹、数据可视化)。

// react-spring
import { useSpring, animated } from 'react-spring';

function SpringBox() {
  const props = useSpring({ x: 100, rotate: 360 });
  return <animated.div style={props} />;
}

// 手势集成
const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }));
const bind = useDrag(({ offset: [x, y] }) => api.start({ x, y }));
return <animated.div {...bind()} style={{ x, y }} />;

📱 React Native 动画:性能是核心分水岭

高性能原生动画:react-native-reanimated

react-native-reanimated 的核心优势在于将动画逻辑移至 UI 线程执行,彻底规避 JavaScript 线程卡顿。其 API 分为 v1(回调式)和 v2(工作lets),v2 更推荐。

// react-native-reanimated (v2)
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

function ReanimatedBox() {
  const offset = useSharedValue(0);
  const animatedStyle = useAnimatedStyle(() => {
    return { transform: [{ translateX: offset.value }] };
  });

  const onPress = () => {
    offset.value = withSpring(100);
  };

  return <Animated.View style={animated_style} onTouchEnd={onPress} />;
}

Lottie 动画播放器:lottie-react-native

该库仅用于渲染设计师导出的 Lottie JSON 文件,不提供程序化动画能力。

// lottie-react-native
import LottieView from 'lottie-react-native';

<LottieView
  source={require('./animation.json')}
  autoPlay
  loop
/>

已过时的简易方案:react-native-animatable

所有动画在 JS 线程运行,性能较差,仅作历史参考。

// react-native-animatable (不推荐)
import Animatable from 'react-native-animatable';

<Animatable.View animation="fadeIn" duration={500} />

⚡ 性能与线程模型对比

渲染线程性能瓶颈适用场景
framer-motionWeb 主线程复杂布局重排Web UI 交互动画
react-springWeb 主线程高频更新计算物理模拟、数据可视化
react-transition-groupWeb 主线程极低(仅类名切换)简单进入/离开过渡
react-native-reanimatedUI 线程几乎无RN 高性能交互动画
lottie-react-native原生渲染线程Lottie 文件复杂度播放预设矢量动画
react-native-animatableJS 线程明显卡顿避免使用

🛠️ 何时选择哪个库?实战场景分析

场景 1:Web 应用中的路由切换动画

  • 需求:页面切换时平滑过渡,支持共享元素(如图片放大)
  • 推荐framer-motion
  • 原因:内置 AnimatePresencelayoutId 完美解决此问题
// framer-motion 路由动画
import { AnimatePresence, motion } from 'framer-motion';

<AnimatePresence mode="wait">
  <motion.div
    key={location.pathname}
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
    exit={{ opacity: 0 }}
  >
    {children}
  </motion.div>
</AnimatePresence>

场景 2:React Native 中的可拖拽抽屉

  • 需求:用户可拖拽面板,松手后自动吸附到最近位置
  • 推荐react-native-reanimated + react-native-gesture-handler
  • 原因:必须 UI 线程执行以保证 60fps 流畅度
// reanimated 拖拽示例(简化)
const dragX = useSharedValue(0);
const gestureHandler = useAnimatedGestureHandler({
  onActive: (event) => { dragX.value = event.translationX; },
  onEnd: () => { dragX.value = withSpring(0); }
});
const style = useAnimatedStyle(() => ({ transform: [{ translateX: dragX.value }] }));

return <PanGestureHandler onGestureEvent={gestureHandler}>
  <Animated.View style={style} />
</PanGestureHandler>;

场景 3:跨平台的数据仪表盘

  • 需求:数字变化带动画(如 0 → 1000),需在 Web 和 RN 一致表现
  • 推荐react-spring
  • 原因@react-spring/web@react-spring/native 提供统一 API
// react-spring 跨平台数字动画
import { useSpring, animated } from '@react-spring/web'; // Web
// import { useSpring, animated } from '@react-spring/native'; // RN

function NumberDisplay({ value }) {
  const { number } = useSpring({ number: value });
  return <animated.text>{number.to(n => n.toFixed(0))}</animated.text>;
}

场景 4:App 启动 Logo 动画

  • 需求:播放设计师提供的品牌 Logo 动效
  • 推荐lottie-react-native(RN)或 lottie-web(Web)
  • 原因:Lottie 是行业标准矢量动画格式,无需编码

📌 关键结论

  • Web 项目

    • 简单过渡 → react-transition-group
    • 交互动画/布局动画 → framer-motion
    • 物理模拟/跨平台 → react-spring
  • React Native 项目

    • 高性能交互动画 → react-native-reanimated
    • 播放 Lottie 动画 → lottie-react-native
    • 避免使用 react-native-animatable
  • 通用原则

    • 优先选择 原生线程执行 的方案(如 Reanimated)
    • 复杂动画尽量 避免在 JS 线程运行
    • 设计师交付的动效优先考虑 Lottie 格式

最终,没有“最好”的库,只有“最合适”的工具。理解每个库的底层机制和设计哲学,才能在正确的时间选用正确的武器。

如何选择: framer-motion vs react-transition-group vs react-native-reanimated vs react-spring vs lottie-react-native vs react-native-animatable

  • framer-motion:

    选择 framer-motion 如果你正在构建 Web 应用,需要高度声明式、可组合的动画 API,并希望利用其内置的布局动画(layout animations)、手势交互(drag, hover)和共享元素过渡。它适合中等复杂度的 UI 动画,如卡片展开、路由切换、悬停反馈等,但不适用于需要精细控制或极致性能的复杂物理模拟。

  • react-transition-group:

    选择 react-transition-group 如果你只需要处理组件的进入(enter)、退出(exit)和出场(appear)过渡,尤其是配合 CSS 类名或内联样式实现简单的淡入淡出、滑动效果。它轻量、专注,适合路由切换、模态框显示/隐藏等场景,但不提供高级动画能力(如手势、物理模拟或原生线程优化);若需更强大功能,应考虑 framer-motionreact-spring

  • react-native-reanimated:

    选择 react-native-reanimated 如果你在 React Native 中需要高性能、流畅的动画(如手势驱动交互动画、自定义转场),尤其是当动画必须在 UI 线程运行以避免 JS 线程阻塞时。它学习曲线较陡,但提供了底层原生动画能力,适合构建复杂交互(如可拖拽面板、自定义导航转场)或对 60fps 有严格要求的场景。

  • react-spring:

    选择 react-spring 如果你需要基于物理弹簧模型的自然动画效果(如弹性、阻尼),并希望在 Web 或 React Native(通过 @react-spring/native)之间共享动画逻辑。它比 CSS 过渡更灵活,适合数据可视化、复杂状态插值或需要精确控制动画曲线的场景,但需注意其声明式 API 可能带来额外的认知负担。

  • lottie-react-native:

    选择 lottie-react-native 如果你需要在 React Native 应用中嵌入由 After Effects 导出的 Lottie JSON 动画文件(例如加载指示器、品牌动效或复杂矢量动画)。它不适用于程序化生成的动画逻辑,而是作为设计师交付资产的播放器,适合复用预制作动画内容而非编写代码驱动的动态行为。

  • react-native-animatable:

    选择 react-native-animatable 仅当你需要快速实现简单的内置动画(如 fadeIn、bounceIn)且项目对性能要求不高。该库已多年未积极维护,所有动画均在 JavaScript 线程运行,可能导致卡顿,不推荐用于新项目;应优先评估 react-native-reanimated 或其他现代替代方案。

framer-motion的README

Motion logo
Motion for React

An open source animation library
for React

npm version npm downloads per month jsDelivr hits (npm) NPM License

npm install motion

Table of Contents

  1. Why Motion?
  2. 🍦 Platforms
  3. 🎓 Examples
  4. ⚡️ Motion+
  5. 👩🏻‍⚖️ License
  6. 💎 Contribute
  7. ✨ Sponsors

Why Motion?

  • Simple API: First-class React, JavaScript, and Vue packages.
  • Hybrid engine: Power of JavaScript combined with native browser APIs for 120fps, GPU-accelerated animations.
  • Production-ready: TypeScript, extensive test suite, tree-shakable, tiny footprint. Batteries included: Gestures, springs, layout transitions, scroll-linked effects, timelines.

🍦 Platforms

Motion is available for React, JavaScript and Vue.

React
import { motion } from "motion/react"

function Component() {
    return <motion.div animate={{ x: 100 }} />
}

Get started with Motion for React.

JavaScript
import { animate } from "motion"

animate("#box", { x: 100 })

Get started with JavaScript.

Vue
<script>
    import { motion } from "motion-v"
</script>

<template> <motion.div :animate={{ x: 100 }} /> </template>

Get started with Motion for Vue.

🎓 Examples

Browse 100+ free and 180+ premium Motion Examples, with copy-paste code that'll level-up your animations whether you're a beginner or an expert.

⚡️ Motion+

A one-time payment, lifetime-updates membership:

  • 180+ premium examples
  • Premium APIs like Cursor and Ticker
  • Visual editing for VS Code (alpha)
  • Private Discord
  • Early access content

Get Motion+

👩🏻‍⚖️ License

  • Motion is MIT licensed.

💎 Contribute

✨ Sponsors

Motion is sustainable thanks to the kind support of its sponsors.

Become a sponsor

Partners

Motion powers the animations for all websites built with Framer, the web builder for creative pros. The Motion website itself is built on Framer, for its delightful canvas-based editing and powerful CMS features.

Framer

Motion drives the animations on the Cursor homepage, and is working with Cursor to bring powerful AI workflows to the Motion examples and docs.

Cursor

Platinum

Linear Figma Sanity Sanity Clerk

Gold

Liveblocks Luma LottieFiles

Silver

Frontend.fyi Firecrawl Puzzmo Bolt.new

Personal