framer-motion vs react-transition-group vs react-native-reanimated vs react-spring vs react-motion vs react-native-animatable
React 动画库的技术选型与深度对比
framer-motionreact-transition-groupreact-native-reanimatedreact-springreact-motionreact-native-animatable类似的npm包:

React 动画库的技术选型与深度对比

framer-motionreact-motionreact-native-animatablereact-native-reanimatedreact-springreact-transition-group 都是用于在 React 应用中实现动画效果的流行库,但它们的设计目标、适用平台和底层机制差异显著。framer-motionreact-spring 是通用的声明式动画库,适用于 Web 和部分跨平台场景;react-motion 是早期基于物理模型的动画方案,现已不再积极维护;react-transition-group 专注于组件进入/离开时的状态管理,不直接处理动画细节;而 react-native-animatablereact-native-reanimated 则专为 React Native 设计,前者提供简单易用的预设动画,后者通过原生线程驱动高性能复杂交互动画。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
framer-motion31,208,50931,0964.6 MB2167 天前MIT
react-transition-group24,645,71110,258244 kB256-BSD-3-Clause
react-native-reanimated3,020,88110,6883.91 MB34410 天前MIT
react-spring919,07129,0518.36 kB1345 个月前MIT
react-motion660,66121,738-1938 年前MIT
react-native-animatable554,6319,95559.8 kB1702 年前MIT

React 动画库深度技术对比:从 Web 到 React Native 的正确选择

在 React 生态中实现流畅动画看似简单,实则涉及渲染线程、声明式抽象、平台差异等深层工程问题。本文将深入剖析六个主流动画库的技术本质、适用边界和真实代码表现,帮助你在架构层面做出精准决策。

⚠️ 首要原则:平台决定技术栈

Web 项目应排除 react-native-animatablereact-native-reanimated —— 它们仅适用于 React Native。同理,React Native 项目无法直接使用 framer-motion(除非通过社区桥接方案,但非官方支持)。react-springreact-transition-group 则同时支持 Web 与 React Native。

此外,react-motion 已被官方标记为废弃(GitHub 仓库归档,README 明确建议迁移到 react-spring),新项目绝不应采用

🧪 核心能力对比:声明式 vs 命令式 vs 状态驱动

场景 1:实现一个简单的淡入淡出动画

这是最常见的 UI 动画需求。各库如何应对?

framer-motion(Web)

import { motion, AnimatePresence } from 'framer-motion';

function FadeComponent({ isVisible }) {
  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          transition={{ duration: 0.3 }}
        />
      )}
    </AnimatePresence>
  );
}

react-spring(Web / React Native)

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

function FadeComponent({ isVisible }) {
  const props = useSpring({
    opacity: isVisible ? 1 : 0,
    config: { duration: 300 }
  });
  
  return <animated.div style={props} />;
}

react-transition-group(Web / React Native)

import { Transition } from 'react-transition-group';

function FadeComponent({ isVisible }) {
  return (
    <Transition in={isVisible} timeout={300}>
      {(state) => (
        <div style={{
          opacity: state === 'entered' ? 1 : 0,
          transition: 'opacity 300ms'
        }} />
      )}
    </Transition>
  );
}

react-native-animatable(React Native)

import Animatable from 'react-native-animatable';

function FadeComponent({ isVisible }) {
  return (
    <Animatable.View
      animation={isVisible ? 'fadeIn' : 'fadeOut'}
      duration={300}
    />
  );
}

💡 关键区别:framer-motionreact-spring 自身驱动动画react-transition-group 仅管理状态,依赖 CSS 实现视觉变化;react-native-animatable 提供预设命名动画

场景 2:实现手势驱动的拖拽交互(如抽屉菜单)

这类高性能交互动画对帧率和响应性要求极高。

framer-motion(Web)

<motion.div
  drag="x"
  dragConstraints={{ left: -100, right: 0 }}
  style={{ x: 0 }}
/>

react-spring(Web / React Native)

import { useDrag } from 'react-use-gesture'; // 需额外依赖

const [{ x }, api] = useSpring(() => ({ x: 0 }));
const bind = useDrag(({ offset: [x] }) => {
  api.start({ x: Math.min(0, Math.max(-100, x)) });
});

return <animated.div {...bind()} style={{ x }} />;

react-native-reanimated(React Native)

import { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

function Draggable() {
  const translateX = useSharedValue(0);
  
  const gesture = Gesture.Pan()
    .onChange((event) => {
      translateX.value = Math.min(0, Math.max(-100, event.translationX));
    })
    .onEnd(() => {
      translateX.value = withSpring(0);
    });
  
  const style = useAnimatedStyle(() => ({
    transform: [{ translateX: translateX.value }]
  }));
  
  return <GestureDetector gesture={gesture}>
    <Animated.View style={style} />
  </GestureDetector>;
}

💡 关键区别:framer-motion 内置手势支持;react-spring 需配合 react-use-gesturereact-native-reanimated 必须与 react-native-gesture-handler 联用,并通过 useSharedValue 在 JS 与原生线程间共享数据。

⚙️ 底层机制:谁在驱动动画?

  • framer-motion:Web 端使用 requestAnimationFrame + CSS transforms,关键动画属性(如 x, y, scale)直接作用于合成层,避免重排重绘。
  • react-spring:基于弹簧物理模型,通过 rafz(requestAnimationFrame 封装)驱动值更新,支持自定义插值器。
  • react-transition-group:零动画逻辑,仅触发 enter/exit 等状态变更,动画完全由外部 CSS 或样式系统实现。
  • react-native-animatable:通过 Animated API(JavaScript 线程)驱动,复杂动画易掉帧。
  • react-native-reanimated:动画逻辑编译为原生代码,在 UI 线程执行,彻底绕过 JavaScript 线程瓶颈。

📱 React Native 专项对比:何时用 Animatable vs Reanimated?

需求推荐方案理由
按钮点击反馈、简单入场动画react-native-animatable一行代码实现,无需配置原生依赖
复杂手势(如 Snapchat 式相机滑动)react-native-reanimated唯一能保证 60fps 的方案
与 React Navigation 转场集成react-native-reanimated官方导航库深度依赖 Reanimated

🌐 跨平台一致性考量

若需同时支持 Web 和 React Native:

  • react-spring 是唯一提供近乎一致 API 的方案(Web 用 animated.div,RN 用 animated.View)。
  • 其他库均存在平台割裂:framer-motion 无 RN 支持;RN 专属库无法用于 Web。

🛠️ 架构建议:组合优于单打独斗

  • Web 项目framer-motion + react-transition-group 组合。前者处理复杂交互动画,后者管理路由/列表过渡状态。
  • React Native 项目:简单动画用 react-native-animatable,复杂交互必须上 react-native-reanimated + react-native-gesture-handler
  • 跨平台项目react-spring 作为统一动画层,但需接受其较重的运行时和学习成本。

📌 总结:按场景精准匹配

场景推荐库替代方案
Web 交互动画(拖拽、手势、共享元素)framer-motionreact-spring
Web 组件进出状态管理react-transition-group自定义状态机
React Native 简单预设动画react-native-animatableRN 内置 Animated
React Native 高性能手势动画react-native-reanimated无(唯一选择)
跨平台物理模型动画react-spring分平台实现
新项目中的 react-motion禁止使用迁移到 react-spring

最终,没有“最好”的动画库,只有“最合适”当前平台、性能需求和团队能力的工具。理解每个库的底层约束和设计哲学,才能避免在错误的场景中强行使用,导致性能瓶颈或维护噩梦。

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

  • framer-motion:

    选择 framer-motion 如果你需要在 Web 端快速实现声明式、高性能的交互动画(如拖拽、手势、共享元素过渡),且希望 API 简洁直观。它内置了对 SVG、布局动画和 Framer 生态的深度支持,适合产品级 Web 应用,但不适用于 React Native。

  • react-transition-group:

    选择 react-transition-group 如果你只需要管理组件挂载/卸载时的生命周期状态(如进入、退出、完成),并将实际动画交由 CSS 或其他动画库实现。它本身不执行动画,而是提供状态钩子,适合与 CSS-in-JS 或传统 CSS 动画结合使用。

  • react-native-reanimated:

    选择 react-native-reanimated 如果你在 React Native 中构建高性能、复杂的手势驱动交互动画(如自定义滚动、拖拽排序、高级转场)。它通过将动画逻辑移至原生线程执行,避免 JavaScript 线程阻塞,但学习曲线陡峭,需熟悉其特有的工作let语法和共享值机制。

  • react-spring:

    选择 react-spring 如果你需要跨平台(Web + React Native)一致的物理模型动画,或要精细控制弹簧参数(张力、摩擦力等)。它采用声明式 API,支持插值和链式动画,适合需要自然动效的场景,但在简单 CSS 过渡场景下可能显得过于重量级。

  • react-motion:

    不要在新项目中使用 react-motion。官方 GitHub 仓库已归档,明确标注为“不再维护”。虽然其基于弹簧物理模型的理念影响深远,但缺乏现代 React 特性支持(如 Concurrent Mode)和性能优化,应优先考虑 react-springframer-motion 等替代方案。

  • react-native-animatable:

    选择 react-native-animatable 如果你在 React Native 中需要快速集成简单的预设动画(如淡入、滑动、缩放),且对性能要求不高。它使用 JavaScript 线程驱动,适合轻量级 UI 反馈,但无法处理复杂手势或高帧率交互动画。

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