使用@react-three/drei的useGLTF首次加载过慢,求性能优化方案
优化NextJS中@react-three/drei加载GLB模型的速度
针对你遇到的1.7MB GLB模型首次加载耗时30-50秒的问题,以下是适配NextJS和@react-three/drei的具体优化方案:
1. 配置NextJS静态资源缓存与压缩
在next.config.js中添加静态资源的缓存策略和压缩配置,让浏览器长期缓存模型文件,同时启用压缩减小传输体积:
/** @type {import('next').NextConfig} */ const nextConfig = { async headers() { return [ { source: '/compressed-robot.glb', headers: [ { key: 'Cache-Control', value: 'public, max-age=31536000, immutable', }, ], }, ]; }, compress: true, // 启用gzip/brotli压缩 }; module.exports = nextConfig;
2. 用Draco压缩进一步减小模型体积
gltf-pipeline的基础压缩还不够,Draco压缩可大幅降低模型几何数据体积。用gltf-pipeline添加Draco压缩:
gltf-pipeline -i input.glb -o compressed-robot-draco.glb -d
然后在代码中配置useGLTF启用Draco加载器:
import { useGLTF, DRACOLoader } from '@react-three/drei'; // 在组件外部配置Draco加载器(需将Draco解码器文件放到public/draco目录下) DRACOLoader.setDecoderPath('/draco/'); function Robot(props) { const { scene } = useGLTF('/compressed-robot-draco.glb', { dracoLoader: new DRACOLoader(), }); return <primitive object={scene} {...props} />; }
注:需下载Draco解码器的draco_decoder.js和draco_wasm_wrapper.js文件,放入NextJS的public/draco目录
3. 提前预加载模型资源
在页面挂载前触发模型预加载,避免Suspense触发时才开始加载:
import { useGLTF } from '@react-three/drei'; import { useEffect } from 'react'; export default function Model() { const ref = useRef(); useEffect(() => { // 页面初始化时预加载模型 useGLTF.preload('/compressed-robot-draco.glb'); }, []); return ( <div className={styles.canvas}> <Suspense fallback={<div className="center">loading</div>}> {/* 原有Canvas代码 */} </Suspense> </div> ); }
4. 优化环境贴图开销
Environment preset="city"会加载较大的环境贴图,换成轻量预设或自定义小尺寸贴图,减少额外加载负担:
// 替换为轻量预设 <Environment preset="studio" /> // 或使用自定义小尺寸HDR贴图 <Environment files="/small-studio.hdr" />
5. 优化服务器/CDN配置
如果是自行部署NextJS,确保服务器启用静态资源的gzip/brotli压缩,同时用CDN托管静态资源,让模型文件从离用户更近的节点分发,降低传输延迟。
内容的提问来源于stack exchange,提问作者Huynh Le
相关产品推荐
相关产品推荐

