WebGL卡顿主因是资源加载、解析、GPU上传阻塞主线程;应优先用DRACO压缩.glb、预加载解码器、Worker解析、禁用视锥剔除、正确使用InstancedMesh。
THREE.js 模型加载慢怎么办不是模型本身太大,而是资源加载、解析、GPU 上传三个环节都在主线程堵着。尤其 GLTFLoader 默认用 FileReader 同步解析二进制,大模型(>10MB)直接触发浏览器长时间无响应。
dracoLoader + 压缩后的 .glb(DRACO 压缩率通常达 60–80%),避免 .gltf + 多个 .bin/.jpg 的 HTTP 请求风暴loader.setMeshoptDecoder(若模型含 meshopt 压缩),比纯 DRACO 解码快 2–3 倍onLoad 回调里直接调用 scene.add();先用 model.traverse(c => c.frustumCulled = false) 关闭视锥剔除,等首次渲染后再恢复requestIdleCallback 能否用于模型解析卸载主线程不能直接用——requestIdleCallback 只适用于轻量 JS 计算,而 glTF 解析涉及大量 ArrayBuffer 操作和 JSON.parse,仍会阻塞空闲时间片。真正有效的分流是 Web Worker。
GLTFLoader.parse() 移入 Worker:用 Worker 加载 gltf-pipeline 或自建解析逻辑,仅把最终的 BufferGeometry 和 Material 序列化后传回主线程THREE.BufferGeometry 无法直接 postMessage,需用 geometry.toJSON() + JSON.parse() 重建,或手动 transfer ArrayBuffer 字段OffscreenCanvas,但目前 THREE.WebGLRenderer 尚未适配,Worker 内无法执行渲染相关操作draco_decoder.js 加载时机DRACO 解码器默认是异步动态 import,但很多项目把它放在 onLoad 之后才加载,导致模型已开始解析却卡在等待解码器——实际是顺序错误。
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/js/draco/'); // 提前设好路径
dracoLoader.preload(); // 主动触发 fetch,不等模型加载才拉/js/draco/ 下存在 draco_decoder.js、draco_wasm_wrapper.js、draco_decoder.wasm 三文件,缺任一都会 fallback 到极慢的 JS 解码draco_decoder.wasm 是否 status 200 且 Type 是 wasm;若显示 script,说明 MIME 类型配置错误(Nginx 需加 types { application/wasm wasm; })InstancedMesh 不生效?InstancedMesh 要求所有实例共享同一 BufferGeometry 和 Material,且不能有独立变换(如每个实例调 mesh.position.set()),否则 THREE.js 自动退化为普通 Mesh。
instancedMesh.setMatrixAt(index, matrix),再调 instancedMesh.instanceMatrix.needsUpdate = true
InstancedBufferGeometry + 自定义 Shader,而非试图混用多个 Material
text lost,建议按屏幕区域分块加载,用 Octree 或 THREE.InstancedMesh + frustumCull 动态启停