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

Next.js中如何仅在指定页面加载特定chunk?

解决Next.js中three.js chunk全局加载的问题

enter image description here

问题描述

在Next.js项目中使用three.js加载3D模型时,通过webpack的splitChunks.cacheGroups拆分出three-js-chunk,成功减小了主chunk体积,但该chunk会在所有页面加载,希望仅在/carmodel页面加载。当前webpack配置如下:

const nextConfig = {
    webpack: (config) => {
        config.optimization.splitChunks.cacheGroups = {
            ...config.optimization.splitChunks.cacheGroups,
            threeJsChunk: {
                chunks: "all",
                name: "three-js-chunk",
                test: /[\\/]node_modules[\\/]three[\\/]/,
            },
        }

        return config
    },
}

解决方案

1. 动态导入three.js(推荐,Next.js原生支持)

无需修改webpack配置,直接在/carmodel页面中异步导入three.js,Next.js会自动将其拆分为独立chunk,仅在访问该页面时加载。

示例代码:

// pages/carmodel.jsx
import { useEffect, useState } from 'react';

export default function CarModelPage() {
  const [threeModule, setThreeModule] = useState(null);

  useEffect(() => {
    // 异步加载three.js
    import('three').then(module => {
      setThreeModule(module);
      init3DModel(module);
    });
  }, []);

  const init3DModel = (THREE) => {
    // 编写你的3D模型初始化逻辑
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer();
    // ...后续逻辑
  };

  return (
    <div>
      {threeModule ? <div id="model-container"></div> : <p>加载中...</p>}
    </div>
  );
}

如果有封装的three.js工具模块,同样可以用动态导入:

import('@/utils/three-helpers').then(helpers => {
  helpers.setupScene();
});

2. 调整webpack splitChunks配置

如果坚持使用webpack配置,需将chunks: "all"改为chunks: "async",仅对异步加载的模块进行拆分,配合页面的动态导入使用:

const nextConfig = {
  webpack: (config) => {
    config.optimization.splitChunks.cacheGroups = {
      ...config.optimization.splitChunks.cacheGroups,
      threeJsChunk: {
        chunks: "async", // 仅处理异步chunk
        name: "three-js-chunk",
        test: /[\\/]node_modules[\\/]three[\\/]/,
        priority: 10, // 提高优先级确保three.js被分到该chunk
      },
    };

    return config;
  },
};

3. 用Next.js dynamic组件懒加载模型组件

如果3D模型是独立组件,使用Next.js的dynamic函数懒加载组件,组件依赖的three.js会随组件一起仅在需要时加载:

// components/CarModel.jsx
import * as THREE from 'three';
import { useEffect } from 'react';

export default function CarModel() {
  useEffect(() => {
    // 初始化3D模型
    const scene = new THREE.Scene();
    // ...逻辑代码
  }, []);

  return <div id="model-wrapper"></div>;
}

在页面中动态导入该组件:

// pages/carmodel.jsx
import dynamic from 'next/dynamic';

// 禁用SSR,因为three.js依赖浏览器API
const CarModel = dynamic(() => import('@/components/CarModel'), {
  loading: () => <p>加载模型中...</p>,
  ssr: false,
});

export default function CarModelPage() {
  return (
    <div>
      <h1>车辆模型展示</h1>
      <CarModel />
    </div>
  );
}

关键说明

  • chunks: "all"会让webpack将three.js关联到所有入口chunk,导致全局加载;改为async或使用动态导入,能确保仅在异步加载场景下才加载该chunk。
  • 如果three.js代码涉及浏览器API(如WebGL),必须禁用SSR,避免服务器端执行报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:47:41