Skip to content

Commit 2e472c5

Browse files
mattlavalleeyyx990803
authored andcommitted
fix(component): clean up memory leak after loading async component completes (fix #8740) (#8755)
* fix(component): clean up memory leak after loading async component completes * fix(async component): accounting for async components with loading property * refactor(component): simplifying memory cleanup logic
1 parent 5f6ef15 commit 2e472c5

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

src/core/vdom/helpers/resolve-async-component.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,14 @@ export function resolveAsyncComponent (
6161
const contexts = factory.contexts = [context]
6262
let sync = true
6363

64-
const forceRender = () => {
64+
const forceRender = (renderCompleted: boolean) => {
6565
for (let i = 0, l = contexts.length; i < l; i++) {
6666
contexts[i].$forceUpdate()
6767
}
68+
69+
if (renderCompleted) {
70+
contexts.length = 0
71+
}
6872
}
6973

7074
const resolve = once((res: Object | Class<Component>) => {
@@ -73,7 +77,7 @@ export function resolveAsyncComponent (
7377
// invoke callbacks only if this is not a synchronous resolve
7478
// (async resolves are shimmed as synchronous during SSR)
7579
if (!sync) {
76-
forceRender()
80+
forceRender(true)
7781
}
7882
})
7983

@@ -84,7 +88,7 @@ export function resolveAsyncComponent (
8488
)
8589
if (isDef(factory.errorComp)) {
8690
factory.error = true
87-
forceRender()
91+
forceRender(true)
8892
}
8993
})
9094

@@ -111,7 +115,7 @@ export function resolveAsyncComponent (
111115
setTimeout(() => {
112116
if (isUndef(factory.resolved) && isUndef(factory.error)) {
113117
factory.loading = true
114-
forceRender()
118+
forceRender(false)
115119
}
116120
}, res.delay || 200)
117121
}

test/unit/features/transition/transition-mode.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ if (!isIE9) {
457457
setTimeout(() => {
458458
resolve({ template: '<div><h1>component B</h1></div>' })
459459
Vue.nextTick(next)
460-
}, (duration + buffer) * 1.5)
460+
}, (duration + buffer) * 1.7)
461461
}
462462
},
463463
data: {

test/unit/modules/vdom/create-component.spec.js

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ describe('create-component', () => {
5858
vnode = createComponent(async, data, vm, vm)
5959
expect(vnode.isComment).toBe(true) // not to be loaded yet.
6060
expect(vnode.asyncFactory).toBe(async)
61+
expect(vnode.asyncFactory.contexts.length).toEqual(1)
6162
}
6263
function loaded () {
6364
vnode = createComponent(async, data, vm, vm)
@@ -68,6 +69,7 @@ describe('create-component', () => {
6869
expect(vnode.elm).toBeUndefined()
6970
expect(vnode.ns).toBeUndefined()
7071
expect(vnode.context).toEqual(vm)
72+
expect(vnode.asyncFactory.contexts.length).toEqual(0)
7173
expect(vm.$forceUpdate).toHaveBeenCalled()
7274
done()
7375
}

0 commit comments

Comments
 (0)