Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOM nodes are being hold by router links in nested views #3321

Open
Spirit04eK opened this issue Sep 14, 2020 · 5 comments
Open

DOM nodes are being hold by router links in nested views #3321

Spirit04eK opened this issue Sep 14, 2020 · 5 comments

Comments

@Spirit04eK
Copy link

Spirit04eK commented Sep 14, 2020

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

  1. Follow this link for open project
  2. Open in new window with codesandbox
  3. Open performance monitor in Google Chrome (emphasize on quantity DOM nodes)
  4. Click on the link "Go to Memory Leak" (pay attention to how it has changed quantity DOM nodes)
  5. Click on the link "Back" (not the home link)
  6. 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

@posva
Copy link
Member

posva commented Sep 14, 2020

This is the same as #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

@posva posva changed the title DOM nodes leak DOM nodes are being hold by router links in nested views Sep 14, 2020
@NazarkinRoman
Copy link

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?

@thiswallz

This comment has been minimized.

@ericcirone

This comment has been minimized.

@jongeir

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants