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

Next.js项目中react-three/fiber在Chrome的WebGL上下文报错求助

问题分析与解决建议

核心问题拆解

你遇到的两个Chrome专属问题存在关联:

  1. Too many active WebGL contexts:Chrome对同时存在的WebGL上下文数量有上限(通常约16个),当页面中BallCanvas实例过多时,旧的上下文会被强制销毁,导致对应Canvas被移除。
  2. shaderSource类型错误:上下文被销毁后,原有的WebGL着色器对象失效,后续尝试调用相关API时就会抛出类型错误。

针对性解决方案

1. 解决WebGL上下文过多问题

方案A:合并多个Canvas为单个Canvas渲染

如果页面中需要展示多个3D球体,不要为每个球体单独创建Canvas,而是在同一个Canvas中渲染多个Ball实例:

// 父组件示例
import React, { Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Preload } from "@react-three/drei";
import Ball from "./Ball";
import CanvasLoader from "../Loader";

const MultiBallCanvas = ({ icons }) => {
  return (
    <Canvas
      frameloop='demand'
      dpr={[1, 2]}
      gl={{ preserveDrawingBuffer: true }}
    >
      <Suspense fallback={<CanvasLoader />}>
        <OrbitControls enableZoom={false} />
        {icons.map((icon, index) => (
          // 通过position区分不同球体位置
          <Ball key={index} imgUrl={icon} position={[index * 4, 0, 0]} />
        ))}
      </Suspense>
      <Preload all />
    </Canvas>
  );
};

方案B:组件卸载时手动清理WebGL资源

如果必须保留多个独立Canvas,在组件卸载时主动清理上下文资源,避免堆积:

import React, { Suspense, useEffect, useRef } from "react";
import { Canvas, useThree } from "@react-three/fiber";
// ...其他导入

const BallCanvas = ({ icon }) => {
  const canvasRef = useRef(null);

  useEffect(() => {
    return () => {
      // 组件卸载时销毁WebGL上下文
      const { gl } = useThree.getState();
      if (gl) {
        gl.dispose();
      }
    };
  }, []);

  return (
    <Canvas
      ref={canvasRef}
      frameloop='demand'
      dpr={[1, 2]}
      gl={{ preserveDrawingBuffer: true }}
    >
      <Suspense fallback={<CanvasLoader />}>
        <OrbitControls enableZoom={false} />
        <Ball imgUrl={icon} />
      </Suspense>
      <Preload all />
    </Canvas>
  );
};

2. 修复Shader类型错误

解决上下文过多问题后,该错误通常会自动消失。如果仍存在,可尝试以下操作:

  • 升级依赖版本:确保@react-three/fiber和@react-three/drei是最新稳定版,旧版本可能存在Chrome专属的WebGL兼容性问题。
  • 移除冲突属性:去掉Decal组件上的flatShading属性,父级mesh已设置该属性,重复设置可能导致Shader编译异常。
  • 验证纹理路径:确保imgUrl指向的资源在Next.js中可正常访问(静态资源需放在public目录,或通过import导入)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:23:20