2.6.10
<!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>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div id="nav">
<button @click="goHome">go to Home</button>
<button @click="goAbout">go to About</button>
</div>
<component :is="current"></component>
</div>
<script>
const Home = {
name: 'Home',
template: `
<div>
<h2>Home</h2>
</div>
`,
}
const About = {
template: `
<div class="about">
<h1>This is an about page</h1>
<input type="text" v-model="input">
</div>
`,
name: 'about',
data: () => ({
input: '',
}),
}
const vm = new Vue({
el: '#app',
data() {
return {
current: 'Home',
}
},
methods: {
goHome() {
this.current = 'Home'
},
goAbout() {
this.current = 'About'
},
},
components: { Home, About },
})
</script>
</body>
</html>
VueComponent count should be stable
VueComponent count keeps increasing.
seems to be related to typing in the input
@posva After further testing. This might not be Vue's fault.
Testing the code above on Chrome Version 72.0.3626.121 (mac) seems to run without any issues and VueComponent count is stable.
it isn't in 74. It could be a bug on Chrome. I've found leaks in the past (https://bugs.chromium.org/p/chromium/issues/detail?id=949587). I didn't test with this one though as it looks like Vue is retaining the component and the browser cannot free it
I can confirm this happens in Chrome 74. When trying to replicate this in Safari, I cannot even see any Vue related objects in their JS allocations inspector, but that is probably just my mistake somehow.
However, if this doesn't happen in the earlier versions of Chrome with the same Vue version, this could be probably forwarded to Chromium project and closed here?
This is especially critical when we talk about large SPA's with tones of data. As far as I can see Chrome 74 is not able to collect much...
https://bugs.chromium.org/p/chromium/issues/detail?id=961494
There is some development regarding this issue.
Recently I have found that there is a problem while input element work with 'v-model'. If I type the content quickly, it cause the high CPU usage.
@posva or anyone knows how to test this with FF devtools and EDGE devtools?
Because we don't have the constructors names in those.
This is happening in other browsers like chrome and ff too.
Thanks.
@posva, i just found out PR #10085 can fix it, my Chrome Version is 74.0.3729.169.
Thanks for checking it out!
Does anybody know if this also happens in the PROD version? As I am not able to filter by "vue" components in Chrome DevTools. I see the same code as the dev version though...
Does anybody know if this also happens in the PROD version? As I am not able to filter by "vue" components in Chrome DevTools. I see the same code as the dev version though...
@clopezcapo Yes it does.
Bufff, and isn't that a huge issue for PROD environments? It looks like is a serious potential killer to me.
Does anybody know if they are aware?
@posva can you please update us on the status of this fix? As still happens in PROD.
this issue is too serious, it take me a long time to find it out...
So... any workarounds so far? Downgrade to v2.6.9?
I can confirm that PR #10085 fixes it for us as well. Is there a plan to merge this?
I also tried this solution, but only half of it worked. chrome80/vue2.6.11/vue-router 3.0.
While vue component has been successfully recycled, three additional listeners have not been removed and dom cannot be recycled. Looking at the heap snapshot,the VueComponent increment is 0, but htmlInputElement has not been recycled, as Performance tools proves. I tracked that these 3 listeners comes from "vue/src/platforms/web/runtime/directs/model.js"-->function onCompositionStart and onCompositionEnd, But I'm not familiar with vue source code .
when input element is deep in a large component, this leads to a large memory leak.
Excuse me?When can I wait until this problem is corrected?There is a serious memory leak in my project, and is in urgent need of a new version!
As a workaround, I wrap my inputs to:
This way 'only' the inputs (which have been edited) itself leak and not the whole component / view.
Simplified:
<template>
<div id="nativeInputContainer">
<input
ref="nativeInput"
id="nativeInput"
v-bind:type="(password) ? 'password' : ''"
v-bind:placeholder="placeholder"
v-bind:value="workingValue"
/>
</div>
</template>
<script>
export default {
name: 'BaseInput',
inheritAttrs: false,
components: {},
props: {
placeholder: {
type: String,
required: false,
default: () => { return '' }
},
value: {
type: String,
required: true
},
password: {
type: Boolean,
required: false,
default: () => { return false }
}
},
data () {
return {
workingValue: ''
}
},
watch: {
value: {
immediate: true,
handler () {
this.workingValue = this.value
}
}
},
methods: {
onInput (event) {
this.workingValue = event.target.value
this.$emit('input', this.workingValue)
},
onChange (event) {
this.$emit('change', this.workingValue)
}
},
mounted () {
// to avoid memory leak (from vue)
// we assign event listeners manually
this.$nextTick(() => {
this.$refs.nativeInput.addEventListener('input', this.onInput)
this.$refs.nativeInput.addEventListener('change', this.onChange)
})
},
beforeDestroy () {
// to avoid memory leak (from vue)
// we remove event listeners manually
this.$refs.nativeInput.removeEventListener('input', this.onInput)
this.$refs.nativeInput.removeEventListener('change', this.onChange)
// to avoid memory leak (from input itself)
// which causes 'this' to be not available for gc
// (undo history keeps input alive)
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=961494#c14
this.$el
.querySelector('#nativeInputContainer')
.removeChild(
this.$el.querySelector('#nativeInput')
)
// maybe not necessary but "always Double Tap"
this.$refs.nativeInput = null
}
}
</script>
<style scoped>
</style>
Most helpful comment
@posva, i just found out PR #10085 can fix it, my Chrome Version is 74.0.3729.169.