Next.js 15中Framer Motion首次加载无动画,刷新后正常的问题咨询
问题分析:与SSR/CSR的关联
这个问题确实和Next.js的SSR(服务端渲染)与CSR(客户端渲染)机制直接相关。Next.js 15默认采用App Router,页面首次加载时会先通过SSR生成静态HTML,再在客户端进行hydration(水合)。Framer Motion的动画依赖客户端DOM环境及React的客户端生命周期,首次hydration过程中,动画的initial到animate的过渡可能因为渲染时机冲突被跳过;而刷新页面时,浏览器直接进行客户端渲染(无SSR的hydration步骤),动画就能正常触发。
解决方案
方案1:通过useAnimation与useEffect控制动画时机
利用React的useEffect确保组件在客户端挂载完成后再启动动画,避免hydration阶段的时机问题:
"use client"; import { motion, useAnimation } from "framer-motion"; import { useEffect } from "react"; export default function Home() { const animationControls = useAnimation(); // 客户端挂载后触发动画 useEffect(() => { animationControls.start({ y: 150 }); }, [animationControls]); return ( <> <motion.h1 initial={{ y: -100 }} animate={animationControls} > ANIMATION TEST </motion.h1> </> ); }
方案2:禁用组件的SSR渲染
如果该动画组件不需要SSR支持,可以通过Next.js的dynamic导入禁用SSR,强制组件仅在客户端渲染:
- 拆分动画组件到单独文件(比如
AnimatedHeading.tsx):
"use client"; import { motion } from "framer-motion"; export default function AnimatedHeading() { return ( <motion.h1 initial={{ y: -100 }} animate={{ y: 150 }} > ANIMATION TEST </motion.h1> ); }
- 在
page.tsx中动态导入并禁用SSR:
import dynamic from 'next/dynamic'; const AnimatedHeading = dynamic(() => import('./AnimatedHeading'), { ssr: false, }); export default function Home() { return <AnimatedHeading />; }
方案3:升级Framer Motion版本
确保你使用的Framer Motion是适配Next.js 15的最新版本,旧版本可能存在与App Router Hydration流程的兼容性问题。执行以下命令升级:
npm update framer-motion
验证效果
应用上述方案后,执行npm run dev启动项目,首次加载页面时动画应该能正常触发,无需刷新页面。
内容的提问来源于stack exchange,提问作者SirGhazian
相关产品推荐
相关产品推荐

