Skip to content

Commit

Permalink
fix(component): clean up memory leak after loading async component co…
Browse files Browse the repository at this point in the history
…mpletes (fix vuejs#8740) (vuejs#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
  • Loading branch information
mattlavallee authored and hefeng committed Jan 25, 2019
1 parent abb7969 commit 493c44a
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 5 deletions.
12 changes: 8 additions & 4 deletions src/core/vdom/helpers/resolve-async-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ export function resolveAsyncComponent (
const contexts = factory.contexts = [context]
let sync = true

const forceRender = () => {
const forceRender = (renderCompleted: boolean) => {
for (let i = 0, l = contexts.length; i < l; i++) {
contexts[i].$forceUpdate()
}

if (renderCompleted) {
contexts.length = 0
}
}

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

Expand All @@ -84,7 +88,7 @@ export function resolveAsyncComponent (
)
if (isDef(factory.errorComp)) {
factory.error = true
forceRender()
forceRender(true)
}
})

Expand All @@ -111,7 +115,7 @@ export function resolveAsyncComponent (
setTimeout(() => {
if (isUndef(factory.resolved) && isUndef(factory.error)) {
factory.loading = true
forceRender()
forceRender(false)
}
}, res.delay || 200)
}
Expand Down
2 changes: 1 addition & 1 deletion test/unit/features/transition/transition-mode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ if (!isIE9) {
setTimeout(() => {
resolve({ template: '<div><h1>component B</h1></div>' })
Vue.nextTick(next)
}, (duration + buffer) * 1.5)
}, (duration + buffer) * 1.7)
}
},
data: {
Expand Down
2 changes: 2 additions & 0 deletions test/unit/modules/vdom/create-component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ describe('create-component', () => {
vnode = createComponent(async, data, vm, vm)
expect(vnode.isComment).toBe(true) // not to be loaded yet.
expect(vnode.asyncFactory).toBe(async)
expect(vnode.asyncFactory.contexts.length).toEqual(1)
}
function loaded () {
vnode = createComponent(async, data, vm, vm)
Expand All @@ -68,6 +69,7 @@ describe('create-component', () => {
expect(vnode.elm).toBeUndefined()
expect(vnode.ns).toBeUndefined()
expect(vnode.context).toEqual(vm)
expect(vnode.asyncFactory.contexts.length).toEqual(0)
expect(vm.$forceUpdate).toHaveBeenCalled()
done()
}
Expand Down

0 comments on commit 493c44a

Please sign in to comment.