javascript-即使在卸载/强制丢失上下文之后,仍在浏览器缓存中维护已加载的gltf

问题描述 投票:1回答:1

我正在React内的three.js场景中加载约10MB的GLTF模型。用户浏览网站时,他们点击了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个回答
0
投票

在同一页面上多次重新启动新的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/上使用的方法,我们在后台只有一个画布,并且只启动一次。然后,我们根据需要显示/隐藏它,而无需每次都安装和卸载新组件。

© www.soinside.com 2019 - 2024. All rights reserved.