File size: 1,609 Bytes
4d70170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import type { DevtoolsApi } from '@vue-devtools/app-backend-api'
import { HookEvents, SharedData } from '@vue-devtools/shared-utils'
import { getInstanceMap } from './tree'

const COMPONENT_HOOKS = {
  beforeCreate: { start: 'create' },
  created: { end: 'create' },
  beforeMount: { start: 'mount' },
  mounted: { end: 'mount' },
  beforeUpdate: { start: 'update' },
  updated: { end: 'update' },
  beforeDestroyed: { start: 'destroy' },
  destroyed: { end: 'destroy' },
}

export function initPerf(api: DevtoolsApi, app, Vue) {
  // Global mixin
  Vue.mixin({
    beforeCreate() {
      applyPerfHooks(api, this, app)
    },
  })

  // Apply to existing components
  getInstanceMap()?.forEach(vm => applyPerfHooks(api, vm, app))
}

export function applyPerfHooks(api: DevtoolsApi, vm, app) {
  if (vm.$options.$_devtoolsPerfHooks) {
    return
  }
  vm.$options.$_devtoolsPerfHooks = true

  for (const hook in COMPONENT_HOOKS) {
    const { start, end } = COMPONENT_HOOKS[hook]
    const handler = function (this: any) {
      if (SharedData.performanceMonitoringEnabled) {
        api.ctx.hook.emit(
          start ? HookEvents.PERFORMANCE_START : HookEvents.PERFORMANCE_END,
          app,
          this._uid,
          this,
          start ?? end,
          api.now(),
        )
      }
    }
    const currentValue = vm.$options[hook]
    if (Array.isArray(currentValue)) {
      vm.$options[hook] = [handler, ...currentValue]
    }
    else if (typeof currentValue === 'function') {
      vm.$options[hook] = [handler, currentValue]
    }
    else {
      vm.$options[hook] = [handler]
    }
  }
}