You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,强制组件仅在客户端渲染:

  1. 拆分动画组件到单独文件(比如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>
  );
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:13:29