【问题标题】:javascript - maintain loaded gltf in browser cache even after unmount / force context lossjavascript - 即使在卸载/强制上下文丢失后也能在浏览器缓存中保持加载的 gltf
【发布时间】:2020-08-28 15:43:53
【问题描述】:

我正在将大约 10MB 的 GLTF 模型加载到 React 中的 three.js 场景中。当用户浏览网站时,他们点击了 3D 模型“场景”,我的 GLTF 模型被加载。当他们完成这个场景时,我会在卸载 react 组件之前进行一些 threejs 清理工作。但是,如果用户重新访问该场景 - 它会再次经历整个加载过程。

有没有办法以某种方式将加载的对象保存在浏览器缓存中,以便即使在卸载 react 组件之后,加载的模型数据也可供后续访问 / 组件安装(即使它是仅在同一浏览器会话中,刷新之前等)?

这是模型加载代码:

loadGLB = loader => {
    if (sceneConfig.modelFormat === 'glb') {
      const dracoLoader = new DRACOLoader();
      dracoLoader.setDecoderPath('three/examples/js/libs/draco/');
      loader.setDRACOLoader(dracoLoader);
    }
  };

const loader = new GLTFLoader().setPath(models.modelPath);
this.loadGLB(loader);
loader.load(`${models.modelToLoad}.${sceneConfig.modelFormat}`, glb => {
      this.object = glb.scene;
      ...
});

和清理:

componentWillUnmount() {
cancelAnimationFrame(this.frameId);
window.removeEventListener('resize', this.handleWindowResize);
this.container.removeChild(this.renderer.domElement);
this.renderer.forceContextLoss();
}

【问题讨论】:

    标签: reactjs caching three.js 3d browser-cache


    【解决方案1】:

    在同一页面上多次重新启动新的 WebGL 上下文会带来一些性能缺陷。最重要的是,每个新上下文都必须将所有纹理和几何图形重新上传到 GPU,这是导致帧交错和闪烁的瓶颈。更不用说清理 + 重建渲染器、着色器、几何体、纹理等所积累的所有内存和 GC 开销。这是轶事,但 FireFox 通常在创建它的第 3 或第 4 个 WebGL 时陷入困境上下文,并且当内存消耗过高时,我让移动设备完全重新加载页面。

    您是否尝试过使用 Portals 以使 <canvas> 位于 React 层次结构之外?这样,您可以将画布放置在您想要的任何位置(例如,在背景中),并且您可以打开/关闭其可见性,而无需在每次想要显示/隐藏它时启动新的 WebGL 上下文。您可以简单地停止渲染并在 CSS 中设置 display: none 以隐藏画布,同时仍然让所有内容处于待机状态,以备下次需要时使用。

    类似这样的:

    if (enabled) {
        renderer.render(scene, cam);
        renderer.domElement.style.display = "block";
    } else {
        // Not rendering when canvas is hidden
        renderer.domElement.style.display = "none";
    } 
    

    这是我们在https://madeinhaus.com/ 上使用的方法我们在后台有一个画布,我们只启动一次。然后我们根据需要显示/隐藏它,而无需每次都安装和卸载新组件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      相关资源
      最近更新 更多