常見原因
https://juejin.im/post/5cb33660e51d456e811d2687
1.意外的全局變量
2.被遺忘的計時器或回調(diào)函數(shù)
echart
- echarts只初始化一次,找不到echarts實(shí)例再去初始化,而不是每次都銷毀再初始化
if(HistoryChart['alarmevent_Num_chart']){
HistoryChart['alarmevent_Num_chart'].dispose();
}
HistoryChart['alarmevent_Num_chart'] = echarts.init(document.getElementById('alarmevent_Num_chart'));
改成
if(!HistoryChart['alarmevent_Num_chart']){
HistoryChart['alarmevent_Num_chart'] = echarts.init(document.getElementById('alarmevent_Num_chart'));
}
three.js
- scene.remove()不要在for..in,或者forEach中執(zhí)行
正確方式
for (let index = scene.children.length-1;index>=0;index--){
scene.remove(scene.children[index]);
}
這是因?yàn)閠hree.js 內(nèi)部是用splice來刪除,刪除完后索引會發(fā)生變化,有些對象就無法被刪除,所以應(yīng)該從數(shù)組尾部刪除
- geometry,material,material.map要執(zhí)行dispose 方法否則不會被刪除
可以用traverse方法遍歷
scene.children[i].traverse(v=>{
if (v.geometry) {
v.geometry.dispose();
}
if (v.material) {
v.material.dispose &&
v.material.dispose();
if (v.material.map) {
v.material.map.dispose &&
v.material.map.dispose();
}
}
})
【補(bǔ)充】20210804
還需要注意的是,UI給的3D模型變了,material.map有可能是一個數(shù)組,原先的代碼需要做一些調(diào)整
// 釋放材質(zhì)
function disposeMaterial(v) {
v.material.dispose &&
v.material.dispose();
if (v.material.map) {
v.material.map.dispose &&
v.material.map.dispose();
}
}
scene.children[i].traverse(v=>{
if (v.geometry) {
v.geometry.dispose();
}
if (v.material) {
// 修改點(diǎn)開始
if (Array.isArray(v.material)) {
v.material.forEach(vv=>{
vv.map && vv.map.dispose()
vv.dispose()
})
} else {
disposeMaterial(v)
}
// 修改點(diǎn)結(jié)束
}
})
VUE
- beforeDestroy
如果有引用第三方庫需要特別注意,在執(zhí)行的時候,頁面已經(jīng)跳轉(zhuǎn)到下一個頁面了,document指向的是下一個頁面的文檔對象,就沒有辦法獲取到要清理的dom節(jié)點(diǎn)了
正確方式
// 使用ref
this.$refs.main_model.removeChild(renderer.domElement)
- 如果有使用echarts
this.chart && this.chart.dispose()
- 如果有使用定時器
clearInterval(this.timer)
I18N
- 額。。。當(dāng)初國際化寫法不當(dāng)導(dǎo)致內(nèi)存泄漏被扣了好多錢,
但是現(xiàn)在一點(diǎn)都想不起是怎么寫的了。。。