参数变化与重建

重建策略

  • 参数变化触发的几何重建必须经过防抖处理(推荐 100–200ms),保证滑杆连续拖动时不因逐帧重建而掉帧。
  • 重建范围必须限定为内容 group 子树;相机位置、OrbitControls 状态、环境动效 rig 均不得因参数变化而重置。

资源释放

两种生命周期,不得合成同一个 dispose 函数。

每次重建释放本次构建创建的资源:

  • 所有 geometry.dispose()
  • 所有 material.dispose(),以及为本次构建创建的纹理

未正确释放会导致用户持续调参过程中 GPU 内存增长,最终页面卡死。

仅在卸载时释放跨重建存活的资源:

  • PMREM 的 RenderTarget 与环境贴图
  • 跨重建复用的共享纹理——程序化噪声纹理、与 2D 画布共用的 CanvasTexture(见渲染质量
  • controls.dispose()renderer.dispose()

两份清单互不容纳对方的条目。每次重建重新生成环境贴图,等于每个防抖周期跑一趟多趟 PMREM 渲染——比你想避免的那个泄漏更贵;每次重建释放共享纹理则更糟——下一帧材质拿到一张死纹理,直接渲染成空白。

注意:遍历内容子树、见到纹理就 dispose 会同时踩中这两个坑——材质引用共享纹理,但并不拥有它。释放你创建的,不要释放你引用的。

尺寸、设备像素比与零尺寸防护

  • renderer.setPixelRatio() 必须封顶——Math.min(window.devicePixelRatio, 2)。在手机或 5K 屏上按 DPR 3 渲染,片元开销是 DPR 2 的 2.25 倍且肉眼无差别,这是「开发机上跑得好好的、到用户那儿掉帧」最常见的原因。
  • 响应容器尺寸变化必须三件齐全:camera.aspectcamera.updateProjectionMatrix()renderer.setSize()。漏了 updateProjectionMatrix() 画面拉伸,漏了 setSize() 还按旧分辨率渲染。
  • 组件可能在隐藏页签或折叠面板中以 0×0 尺寸挂载。ResizeObserver 收到 0×0 尺寸时必须忽略并保留既有视图状态,待获得非零尺寸后再执行初始化或自适应,确保页签切换后视图完好。
Esc
输入关键词搜索全部文档 · 切换 · 打开