framework7io / framework7-vue

Deprecated! Build full featured iOS & Android apps using Framework7 & Vue
http://framework7.io/vue/
MIT License
674 stars 150 forks source link

F7 Webpack - VueComponents never garbage collected #263

Closed maxneuvians closed 7 years ago

maxneuvians commented 7 years ago

Hi

I am really enjoying f7-vue but I am running into a problem where loading a new page adds VueComponents to the memory heap without cleaning them up.

The issue in one of my applications is that after 80-100 navigation events the memory usage is out of control.

To reproduce this you can use do the following:

Should it not remain at 103 because those 9 components are already in memory? Or at least they should be freed and then replaced by the new ones?

I have tried a couple of configuration options like turning off domCaching on the view. When I add reload to the links I can see that the destroyed() event hook is called on the components but they do not get removed from memory.

Please let me know if I am misunderstanding an implementation detail here.

Thanks for all your hard work!

maxneuvians commented 7 years ago

It may not be specific to f7-router events. In my application I changed some components to trigger their existence based on v-if statements. When v-if switched back to false the destroyed() callback was invoked but the VueComponents were still in the memory heap. I made sure they did not have any external DOM listeners attached. I will try to reproduce this one in a simpler repo a well.

scriptPilot commented 7 years ago

Same for me. The problem is, if there is a div with an ID on it, you have it multiple times. I have had some issues out of that behavior.

What I tried to solve that situation - add the following configuration parameters at init:

But same behavior ...

scriptPilot commented 7 years ago

Linked to https://github.com/framework7io/Framework7-Vue/issues/197 as well, where you can find a workaround for specific cases.

maxneuvians commented 7 years ago

These bugs affect the actual DOM items and they do get removed from the DOM - they don't get removed from the memory heap though.

scriptPilot commented 7 years ago

More related issues:

vsg24 commented 7 years ago

Any updates on this?

maxneuvians commented 7 years ago

Hi,

I have created a sample repo:

https://github.com/maxneuvians/vueF7MemoryLeakExample

It illustrates the issue very nicely. You create a component using a v-if toggle which has a lot of data. In this case 100 item list. You toggle it on and off repeatedly. The destroyed callback is invoked, but the VueComponents are not cleared from memory.

After 18 toggles I went from 20 MB heap size to 145 MB heap size.

I tried this in plain F7Vue without webpack and it did not happen there - no VueComponents were created.

macdonst commented 7 years ago

@scriptPilot I sat with @maxneuvians today and saw the problem first hand.

nolimits4web commented 7 years ago

@maxneuvians so the problem is in webpack?

nolimits4web commented 7 years ago

I currently can’t check it as I’m on vacation, but if you use some custom list component or just plain <ul><li> instead of f7-list and f7-list-item, problem still exist?

maxneuvians commented 7 years ago

@nolimits4web I could not replicate it in https://github.com/nolimits4web/Framework7-Vue-Simple-Template with the exact same component set up. I replaced the f7-list with ul and f7-list-item with li and it did not cause a problem. However, if I do:

<div>
    <f7-button v-for="number in data" :text="number"></f7-button>
 </div>

It will still retain the components. So this is not specific to just <f7-list>

macdonst commented 7 years ago

@nolimits4web using @maxneuvians example I can reproduce the issue with all of our phonegap-template-vue-f7-* templates that use webpack.

nolimits4web commented 7 years ago

Well ok, so how to unload component from browser memory? As far as I know browsers don’t really allow to control memory. Maybe problem related to Vue, such v-if thing is controlled by Vue, F7 doesn’t do anything with it. Events attaching/detaching is also controlled by Vue

maxneuvians commented 7 years ago

Without in-depth knowledge I would say that memory gets freed through the garbage collector. The memory is freed when it is no longer linked to its root.

This issue https://github.com/vuejs/vue/issues/6759 implies that the count of VueComponents should decrease after the component is destroyed. This seems to be specific to keep-alive though.

nolimits4web commented 7 years ago

Ok, the issue is in the Vue itself, here is a simple test case https://jsfiddle.net/muy6kfn2/3/

nolimits4web commented 7 years ago

And looks like it is fixed in latest version https://jsfiddle.net/0qb0kfmr/3/

nolimits4web commented 7 years ago

From my findings the issue is caused by not detached event in case of component rendered with render function and have event assigned inside with on

nolimits4web commented 7 years ago

So closing as not F7 issue

maxneuvians commented 7 years ago

@nolimits4web Thank you for your work on the issue! Much appreciated!

macdonst commented 7 years ago

Thanks @nolimits4web