2
0
Эх сурвалжийг харах

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
Matt Lavallee 7 жил өмнө
parent
commit
2e472c5e5e

+ 8 - 4
src/core/vdom/helpers/resolve-async-component.js

@@ -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>) => {
@@ -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)
       }
     })
 
@@ -84,7 +88,7 @@ export function resolveAsyncComponent (
       )
       if (isDef(factory.errorComp)) {
         factory.error = true
-        forceRender()
+        forceRender(true)
       }
     })
 
@@ -111,7 +115,7 @@ export function resolveAsyncComponent (
             setTimeout(() => {
               if (isUndef(factory.resolved) && isUndef(factory.error)) {
                 factory.loading = true
-                forceRender()
+                forceRender(false)
               }
             }, res.delay || 200)
           }

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

@@ -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: {

+ 2 - 0
test/unit/modules/vdom/create-component.spec.js

@@ -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)
@@ -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()
     }