Skip to content

Commit

Permalink
fix(内存): 修复调用clearData之后,依然保持对节点的引用导致的内存溢出bug (#1993)
Browse files Browse the repository at this point in the history
Co-authored-by: tianmingjian <[email protected]>
Co-authored-by: DymoneLewis <[email protected]>
  • Loading branch information
3 people authored Dec 11, 2024
1 parent 5773099 commit afb0593
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
10 changes: 7 additions & 3 deletions examples/vue3-app/src/views/PerformanceNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
>添加个节点和边:</el-button
>
<el-button type="primary" @click="addDomNumber(domNumber, false)">只添加节点:</el-button>
<el-button type="warning" @click="clearAll">清空</el-button>
<span>element元素数量:{{ elementNumber }}</span>
<span>EChart元素数量:{{ eChartNumber }}</span>
<span>节点数量:{{ nodeNumber }}</span>
Expand All @@ -25,7 +26,7 @@
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, reactive } from 'vue'
import { ref, onMounted, nextTick, reactive, shallowRef } from 'vue'
import { ElNotification } from 'element-plus'
import LogicFlow from '@logicflow/core'
import { register } from '@logicflow/vue-node-registry'
Expand All @@ -39,13 +40,13 @@ import { getTotalDOMNumber } from '@/utils/performance'
import { getRandom } from '@/utils/math'
const containerRef = ref<HTMLDivElement | null>(null)
const lfRef = ref<LogicFlow | null>(null)
const lfRef = shallowRef<LogicFlow | null>(null)
const elementNumber = ref<number>(0)
const eChartNumber = ref<number>(0)
const totalDOMNumber = ref<number>(0)
const eventType = ref<undefined | string>()
const nodeNumber = ref<number>(0)
const domNumber = ref<number>(10)
const domNumber = ref<number>(500)
const edgeNumber = ref<number>(0)
const id = ref<number>(0)
Expand Down Expand Up @@ -151,6 +152,9 @@ const addDomNumber = (number: number, hasEdge: boolean) => {
}
}
const clearAll = () => {
lfRef.value?.clearData()
}
// 模拟自动添加节点
// const autoAddNode = (time: number, count: number, nodeNumber: number) => {
// let total = 0
Expand Down
5 changes: 2 additions & 3 deletions examples/vue3-app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueDevTools from 'vite-plugin-vue-devtools'

// vite-plugin-vue-devtools 会导致所有的vue节点被记录在 全局变量 __VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__ 上,导致内存溢出的bug
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), VueDevTools()],
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/LogicFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,8 @@ export class LogicFlow {
*/
clearData() {
this.graphModel.clearData()
// 强制刷新数据, 让 preact 清除对已删除节点的引用
this.render({})
}

/*********************************************************
Expand Down
32 changes: 26 additions & 6 deletions packages/core/src/model/GraphModel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { find, forEach, map, merge, isBoolean, debounce, isEqual,isNil } from 'lodash-es'
import {
find,
forEach,
map,
merge,
isBoolean,
debounce,
isEqual,
isNil,
} from 'lodash-es'
import { action, computed, observable } from 'mobx'
import {
BaseEdgeModel,
Expand Down Expand Up @@ -454,14 +463,20 @@ export class GraphModel {
// this.resize()
// }
if (!graphData) {
this.nodes = []
this.edges = []
this.clearData()
return
}
this.elementsModelMap.clear()
this.nodeModelMap.clear()
this.edgeModelMap.clear()

if (graphData.nodes) {
this.nodes = map(graphData.nodes, (node: NodeConfig) =>
this.getModelAfterSnapToGrid(node),
)
this.nodes = map(graphData.nodes, (node: NodeConfig) => {
const nodeModel = this.getModelAfterSnapToGrid(node)
this.elementsModelMap.set(nodeModel.id, nodeModel)
this.nodeModelMap.set(nodeModel.id, nodeModel)
return nodeModel
})
} else {
this.nodes = []
}
Expand Down Expand Up @@ -1548,6 +1563,11 @@ export class GraphModel {
@action clearData(): void {
this.nodes = []
this.edges = []

// 清除对已清除节点的引用
this.edgeModelMap.clear()
this.nodeModelMap.clear()
this.elementsModelMap.clear()
}

/**
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/view/node/BaseNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
if (this.modelDisposer) {
this.modelDisposer()
}

// 以下是 mobx-preact 中 componentWillUnmount 的回调逻辑,但是不知道出于什么考虑,mobx-preact 没有混入这一段逻辑
// @ts-ignore
if (this.render.$mobx) {
// @ts-ignore
this.render.$mobx.dispose()
}
}

componentDidMount() {}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/view/node/HtmlNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class HtmlNode<
}

componentWillUnmount() {
super.componentWillUnmount()
this.rootEl.innerHTML = ''
}

Expand Down

0 comments on commit afb0593

Please sign in to comment.