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

Next.js/ReactJS页面切换时Spline重复渲染问题咨询

Spline 3D页面切换后重复渲染问题解决方案

问题背景

我制作了Spline 3D设计并部署至网站,Spline本身运行正常,但页面切换时存在异常:从首页切换到关于页,再返回首页时,Spline会重复渲染。

现象说明

  • 首页初始状态:Spline正常渲染
  • 切换至关于页状态:Spline随首页组件卸载
  • 返回首页状态:Spline重新加载,出现重复渲染

代码场景

使用Next.js App Router,首页page.tsx中直接引入Spline组件:

import Spline from '@splinetool/react-spline';

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <Spline scene="https://prod.spline.design/xxxx/scene.splinecode" />
    </main>
  );
}

核心原因

路由切换时,首页组件被完全卸载,返回时重新挂载,导致Spline组件从头初始化,出现重复渲染(实际是重新加载)。


可行解决方案

1. 缓存Spline组件(推荐)

用React.cache包裹Spline组件,确保组件实例在路由切换后复用:

import Spline from '@splinetool/react-spline';

// 缓存Spline组件实例
const CachedSpline = React.cache(() => (
  <Spline scene="https://prod.spline.design/xxxx/scene.splinecode" />
));

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <CachedSpline />
    </main>
  );
}

2. 全局布局挂载+显隐控制

将Spline放到根布局layout.tsx中,通过CSS控制在不同页面的显示/隐藏,避免组件卸载:

// app/layout.tsx
import { usePathname } from 'next/navigation';
import Spline from '@splinetool/react-spline';
import './globals.css';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  return (
    <html lang="en">
      <body>
        {/* 仅在首页显示Spline */}
        <div className={`spline-bg ${pathname !== '/' ? 'hidden' : ''}`}>
          <Spline scene="https://prod.spline.design/xxxx/scene.splinecode" />
        </div>
        {children}
      </body>
    </html>
  );
}

对应的globals.css:

.spline-bg {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
}
.hidden {
  display: none;
}

3. 手动管理Spline实例

通过useRef保存Spline实例,避免组件卸载时销毁实例:

import { useEffect, useRef } from 'react';

export default function Home() {
  const splineContainer = useRef<HTMLDivElement>(null);
  const splineInstance = useRef<any>(null);

  useEffect(() => {
    if (!splineInstance.current && splineContainer.current) {
      // 手动初始化Spline
      splineInstance.current = new window.SplineViewer(splineContainer.current, {
        scene: "https://prod.spline.design/xxxx/scene.splinecode"
      });
    }

    // 组件卸载时不销毁实例(或者根据路由判断是否销毁)
    return () => {};
  }, []);

  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <div ref={splineContainer} className="w-full h-full" />
    </main>
  );
}

内容的提问来源于stack exchange,提问作者Azura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:48:12