Vue: Memory leak with functional component

Created on 4 Sep 2019  ·  4Comments  ·  Source: vuejs/vue

Version

2.6.10

Reproduction link

https://github.com/shenron/vuejs-memory-leak

Steps to reproduce

Try to look memory after toggled a functional component.

What is expected?

As standard component, no detached element should be visible.

What is actually happening?

Each time there is n new detached element.


I'm sorry I can't reproduce this on JSFiddle: https://jsfiddle.net/shenron/cq697f2z/, I created a fresh new VueJS project with Vue cli: https://github.com/shenron/vuejs-memory-leak

Most helpful comment

That problem is actual
@posva

P.s.
sorry, create another issue https://github.com/vuejs/vue-hot-reload-api/issues/80

All 4 comments

The second argument to h/createElement is an object:

h('button', {}, 'placeholder')

Doing that shows no leak

Thank you for this answer, sorry for my mistake. I fixed this on the repo but I still have the same memory leak:

image

export default {
  functional: true,
  render(createElement, { children }) {
    return createElement('button', {}, children);
  },
};

Make sure, you are garbage collecting in between snapshots. I get a constant detached count and also this:

Screen Shot 2019-09-04 at 18 02 43

Here is the page I used:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>leak test</title>
  </head>
  <body>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vue-router"></script>

    <div id="app">
      <router-link to="/">empty</router-link> |
      <router-link to="/functional-button">functional button</router-link> |
      <router-link to="/standard-button">standard button</router-link> |
      <router-view :key="$route.fullPath"></router-view>
    </div>

    <script>
      Vue.component('standard-button', {
        functional: false,
        render(h) {
          return h('button', {}, ['placeholder'])
        },
      })

      Vue.component('functional-button', {
        functional: true,
        render(h, { children }) {
          return h('button', children)
        },
      })

      const HomeComponent = {
        template: '<span></span>',
      }

      const StandardButton = {
        template:
          '<div><functional-button v-for="i in 1000" :key="i">My Button</functional-button></div>',
      }

      const FunctionalButton = {
        template:
          '<div><standard-button v-for="i in 1000"></standard-button></div>',
      }

      const routes = [
        {
          path: '/',
          component: HomeComponent,
        },
        {
          path: '/functional-button',
          component: FunctionalButton,
        },
        {
          path: '/standard-button',
          component: StandardButton,
        },
      ]

      const router = new VueRouter({
        routes,
      })

      new Vue({
        el: '#app',
        router,
      })
    </script>
  </body>
</html>

That problem is actual
@posva

P.s.
sorry, create another issue https://github.com/vuejs/vue-hot-reload-api/issues/80

Was this page helpful?
0 / 5 - 0 ratings