Skip to content

Commit

Permalink
fix: memory leak, use hook events (thanks #522)
Browse files Browse the repository at this point in the history
  • Loading branch information
pimlie committed Feb 26, 2020
1 parent 9655a81 commit 21621e1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 41 deletions.
69 changes: 34 additions & 35 deletions src/shared/mixin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { triggerUpdate } from '../client/update'
import { isUndefined, isFunction } from '../utils/is-type'
import { find } from '../utils/array'
import { ensuredPush } from '../utils/ensure'
import { rootConfigKey } from './constants'
import { hasMetaInfo } from './meta-helpers'
import { addNavGuards } from './nav-guards'
Expand Down Expand Up @@ -80,7 +79,7 @@ export default function createMixin (Vue, options) {
// if computed $metaInfo exists, watch it for updates & trigger a refresh
// when it changes (i.e. automatically handle async actions that affect metaInfo)
// credit for this suggestion goes to [Sébastien Chopin](https://github.com/Atinux)
ensuredPush($options, 'created', function () {
this.$on('hook:created', function () {
this.$watch('$metaInfo', function () {
triggerUpdate(options, this[rootKey], 'watcher')
})
Expand All @@ -99,7 +98,7 @@ export default function createMixin (Vue, options) {
if (!$root[rootConfigKey].initializedSsr) {
$root[rootConfigKey].initializedSsr = true

ensuredPush($options, 'beforeMount', function () {
this.$on('hook:beforeMount', function () {
const $root = this
// if this Vue-app was server rendered, set the appId to 'ssr'
// only one SSR app per page is supported
Expand All @@ -110,7 +109,7 @@ export default function createMixin (Vue, options) {
}

// we use the mounted hook here as on page load
ensuredPush($options, 'mounted', function () {
this.$on('hook:mounted', function () {
const $root = this[rootKey]

if (!$root[rootConfigKey].initialized) {
Expand Down Expand Up @@ -150,6 +149,36 @@ export default function createMixin (Vue, options) {
}
}

this.$on('hook:destroyed', function () {
// do not trigger refresh:
// - when user configured to not wait for transitions on destroyed
// - when the component doesnt have a parent
// - doesnt have metaInfo defined
if (!this.$parent || !hasMetaInfo(this)) {
return
}
delete this._hasMetaInfo

this.$nextTick(() => {
if (!options.waitOnDestroyed || !this.$el || !this.$el.offsetParent) {
triggerUpdate(options, this.$root, 'destroyed')
return
}

// Wait that element is hidden before refreshing meta tags (to support animations)
const interval = setInterval(() => {
if (this.$el && this.$el.offsetParent !== null) {
/* istanbul ignore next line */
return
}

clearInterval(interval)

triggerUpdate(options, this.$root, 'destroyed')
}, 50)
})
})

// do not trigger refresh on the server side
if (this.$isServer) {
/* istanbul ignore next */
Expand All @@ -158,40 +187,10 @@ export default function createMixin (Vue, options) {

// no need to add this hooks on server side
updateOnLifecycleHook.forEach((lifecycleHook) => {
ensuredPush($options, lifecycleHook, function () {
this.$on(`hook:${lifecycleHook}`, function () {
triggerUpdate(options, this[rootKey], lifecycleHook)
})
})
},
// TODO: move back into beforeCreate when Vue issue is resolved
destroyed () {
// do not trigger refresh:
// - when user configured to not wait for transitions on destroyed
// - when the component doesnt have a parent
// - doesnt have metaInfo defined
if (!this.$parent || !hasMetaInfo(this)) {
return
}
delete this._hasMetaInfo

this.$nextTick(() => {
if (!options.waitOnDestroyed || !this.$el || !this.$el.offsetParent) {
triggerUpdate(options, this.$root, 'destroyed')
return
}

// Wait that element is hidden before refreshing meta tags (to support animations)
const interval = setInterval(() => {
if (this.$el && this.$el.offsetParent !== null) {
/* istanbul ignore next line */
return
}

clearInterval(interval)

triggerUpdate(options, this.$root, 'destroyed')
}, 50)
})
}
}
}
6 changes: 0 additions & 6 deletions src/utils/ensure.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,3 @@ export function ensureIsArray (arg, key) {
}
return arg
}

export function ensuredPush (object, key, el) {
ensureIsArray(object, key)

object[key].push(el)
}

0 comments on commit 21621e1

Please sign in to comment.