vue-router
vue-router copied to clipboard
DOM nodes are being hold by router links in nested views
Version
3.4.3
Reproduction link
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.min.js"></script>
<div id="app">
<router-link :to="{name: 'memory_leak'}">Go to Memory Leak</router-link>
<router-link to="/">home (using this link won't hold memory)</router-link>
<router-view></router-view>
</div>
<script>
const leak = {
template: `
<div style="word-break: break-all;">
<router-link to="/">Back</router-link>
<br>
<span v-for="span in spans" :key="span.id">{{ span.text }}</span>
</div>
`,
data() {
return {
spans: [],
}
},
created() {
for (let i = 1; i <= 10; i++) {
let obj = {
id: i,
text: Array(10).fill('a').join(''),
}
this.spans.push(obj)
}
},
}
const ParentMemoryLeak = {
template: `
<div>
<h1>Parent Memory leak</h1>
<br>
<router-view></router-view>
</div>
`,
name: 'ParentMemoryLeak',
}
const routes = [
{
path: '/parent-memory-leak',
component: ParentMemoryLeak,
children: [
{
path: 'memory-leak',
name: 'memory_leak',
component: leak,
},
],
},
{ path: '/', component: ParentMemoryLeak },
]
const router = new VueRouter({
routes,
})
new Vue({
el: '#app',
router,
})
</script>
</body>
</html>
Steps to reproduce
- Follow this link for open project
- Open in new window with codesandbox
- Open performance monitor in Google Chrome (emphasize on quantity DOM nodes)
- Click on the link "Go to Memory Leak" (pay attention to how it has changed quantity DOM nodes)
- Click on the link "Back" (not the home link)
- Amount DOM nodes not changed.
P.S. If you do this procedure several times amount DOM nodes should changed, but the original will remain forever.
What is expected?
it is expected that after each click on the link "back" DOM nodes will be cleared.
What is actually happening?
Now, they are cleared only after the first transition, but still remain in the memory DOM nodes for the first transition.
https://youtu.be/bjz1N0BD_2c
This is the same as https://github.com/vuejs/vue-router/issues/1319. It seems to be related to RouterLink being used in the nested view, so if anybody wants to debug it, they can start there. Also using a link outside of the nested view avoid the memory hold. The fix could also be in Vue Core and there could also be an already submitted PR.
Note this is not a leak as memory consumption doesn't grow, it's kept stable. But something is holding into memory. I updated the reproduction as well
Note this is not a leak as memory consumption doesn't grow, it's kept stable
AFAIK, detached DOM elements doesn't count to JS heap size, but they are still stored in the memory. Could you explain why this shouldn't be treated as memory leak?
same problem here, whenever I change routes, DOM Nodes and JS Listeners increases without cleaning
I am seeing the same issue. SPA using Vue 2 with vue-router and on each route change the DOM Nodes and JS event listeners are increasing and doesn't look like anything is being cleaned up.