前进:我已经查看了我能找到的每三个.js内存泄漏帖子,其中大部分内容已经过时,已弃用功能。即使是较新的也不会在这种情况下产生任何结果。
客户端框架:React v15.5.4,ThreeJS r88。
以下是JS Heap的性能简介:
渲染循环期间一切正常。在我更改组件并在组件componentWillUnmount生命周期方法中触发清理功能后,我希望蓝色的JS Heap行位于底部。不幸的是,这种情况并非如此。蓝线变平的地方是组件发生变化并执行清理代码的地方。不知怎的,堆增加???
以下是将对象添加到场景和清理/处理机制的代码:
/*
* This is how the models are added to the scene. A listener is added to each object in the scene
* to invoke Builder.prototype.model._dispose when the remove event is triggered
*/
//..
init: {
// ...
_modelInScene: function( modelData ) {
const { dimensions, index, model, sectionModelsArray, tableConfig, type } = modelData;
sectionModelsArray.push( model );
// size and position model
//Builder.model._sizeAndPosition( { model, dimensions, type, index }, tableConfig );
// add model to scene
_threejs.scene.add( model );
model.addEventListener( "removed", Builder.prototype.model._dispose );
// store type of model on model meshes so that we can get this information during raycasting
model.traverse( function ( child ) {
child.addEventListener( "removed", Builder.prototype.model._dispose );
if ( child instanceof THREE.Mesh ) {
child._modelType = type;
}
} );
},
// ...
},
//..
/*
* This is the function triggered in componentWillUnmount method of the react component that contains
* the three js scene. In this function I remove all top level children from the scene. This triggers
* the listeners for the remove event and calls the dispose function which releases geometry, materials,
* and removes nested objects from scene triggering their remove events etc...
*/
//...
cleanup: function() {
// dispose of scene listeners
Builder.prototype._removeListeners();
// TODO - implement cache
// clear the model cache
//Builder.prototype.model._clearCache();
// clear the texture cache
//Builder.prototype.texture._clearCache();
// remove tableConfig from _threejs object
_tableConfig = null;
// reset tableConfig in redux store
_dispatch( removeTable() );
// remove all children from scene
while( _threejs.scene.children.length > 0 ) {
_threejs.scene.remove( _threejs.scene.children[ 0 ] );
}
// remove reference to animations in the heightAnimationController
if ( _threejs.heightAnimationController ) _threejs.heightAnimationController.dispose();
// reset _shouldCastRay to false
_shouldCastRay = false;
// dispose of controls listeners
_threejs.controls.dispose();
// dispose of rendering context
_threejs.renderer.dispose();
// reset _threejs object
_threejs = {
camera: null,
controls: null,
heightAnimationController: null,
lookAt: null,
mouseCoords: null,
raycaster: null,
raycasterTargetModels: [],
renderer: null,
scene: null,
sceneHeight: 0,
sceneWidth: 0,
tableConfig: null
};
// cancel requestAnimationFrame from Builder.prototype._animate3js
cancelAnimationFrame( _animationFrameId );
},
//...
/*
* Dispose function invoked by remove listeners
*/
//...
model: {
//..
_dispose: function() {
const target = arguments[ 0 ].target;
if ( target instanceof THREE.Mesh ) {
if ( target.geometry ) {
target.geometry.dispose();
}
if ( target.material ) {
if ( target.material.bumpMap ) target.material.bumpMap.dispose();
if ( target.material.envMap ) target.material.envMap.dispose();
if ( target.material.lightMap ) target.material.lightMap.dispose();
if ( target.material.map ) target.material.map.dispose();
if ( target.material.normalMap ) target.material.normalMap.dispose();
if ( target.material.specularMap ) target.material.specularMap.dispose();
target.material.dispose();
}
} else {
while ( target.children.length > 0 ) {
target.remove( target.children[ 0 ] );
}
}
},
//..
},
//..
在清理过程中,我处理了OrbitControls,WebGLRenderingContext,所有Textures和Geometries,并删除了所有与three.js相关的引用。
此外,我要更改的反应组件只是一个空div元素。这个无状态组件中没有任何东西可以解释堆中的跳转。
我花了很多时间查看three.js源代码,在stackoverflow上,以及其他试图解决这个问题的网站。非常感谢任何帮助!
编辑:添加到场景中的“模型”是THREE.Scene
的实例,并包含其中包含网格的Object3D容器。它们从混合器导出并通过THREE.ObjectLoader
加载。以防万一是相关的。
以下是时间表:
我可以提供任何要求的信息,目前是纺车:(
编辑#3:
我已经将每次初始化和解构模型的泄漏减少到大约100kb。不幸的是,快照之间的比较在我看来是相当模糊的。 (虽然我不熟悉泄漏!)
看起来一切都回归到THREE或webpackJsonp。有什么建议吗?我想如果我想使用库,这可能是我必须要忍受的。