File size: 4,359 Bytes
c824890
 
 
 
 
 
 
 
 
 
6d6e4bf
 
c824890
 
 
 
 
 
 
57a062e
c824890
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57a062e
c824890
 
 
 
 
 
 
 
 
57a062e
c824890
 
 
 
 
 
 
57a062e
c824890
 
 
 
 
 
 
 
 
57a062e
c824890
 
 
57a062e
c824890
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57a062e
 
c824890
57a062e
c824890
 
 
 
 
 
 
 
 
57a062e
c824890
57a062e
c824890
 
 
 
 
 
 
 
 
 
 
57a062e
c824890
57a062e
c824890
 
 
 
 
 
 
 
 
 
57a062e
c824890
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const raf = require('licia/raf')
const LunaPerformanceMonitor = require('luna-performance-monitor').default
const now = require('licia/now')

module.exports = function (eruda) {
  let { evalCss } = eruda.util

  class Monitor extends eruda.Tool {
    constructor() {
      super()
      this.name = 'monitor'
      this.displayName = 'モニター'
      this._style = evalCss(
        require('./style.scss') +
          require('luna-performance-monitor/luna-performance-monitor.css')
      )
    }
    init($el, container) {
      super.init($el, container)
      // 各メトリクス表示用の要素を生成
      $el.html(
        '<div class="eruda-fps"></div><div class="eruda-memory"></div><div class="eruda-dom-nodes"></div>'
      )

      this._initFps($el.find('.eruda-fps').get(0))
      if (performance.memory) {
        this._initMemory($el.find('.eruda-memory').get(0))
      }
      this._initDomNodes($el.find('.eruda-dom-nodes').get(0))

      eruda.get().config.on('change', this._onThemeChange)
    }
    show() {
      super.show()

      // 表示開始時にモニターを開始
      this._fpsMonitor.start()
      if (this._memoryMonitor) {
        this._memoryMonitor.start()
      }
      this._domNodesMonitor.start()
    }
    hide() {
      super.hide()

      // 非表示時にモニターを停止
      this._fpsMonitor.stop()
      if (this._memoryMonitor) {
        this._memoryMonitor.stop()
      }
      this._domNodesMonitor.stop()
    }
    destroy() {
      // クリーンアップ処理
      eruda.get().config.off('change', this._onThemeChange)
      this._fpsMonitor.destroy()
      if (this._memoryMonitor) {
        this._memoryMonitor.destroy()
      }
      super.destroy()
      evalCss.remove(this._style)
    }
    _getColor() {
      // 現在のテーマのアクセントカラーを取得
      return eruda.util.evalCss.getCurTheme().accent
    }
    _getTheme() {
      // 現在のテーマがダークかライトかを判定
      return eruda.util.isDarkTheme() ? 'dark' : 'light'
    }
    _initFps(el) {
      let frames = 0
      let prevTime = 0
      let fps = 0
      let fpsId
      function updateFPS() {
        frames++
        const time = now()
        if (time > prevTime + 1000) {
          fps = Math.round((frames * 1000) / (time - prevTime))
          prevTime = time
          frames = 0
        }
        fpsId = raf(updateFPS)
      }
      updateFPS()

      // FPS モニター作成
      const fpsMonitor = new LunaPerformanceMonitor(el, {
        title: 'FPS(フレームレート)',
        color: this._getColor(),
        smooth: false,
        theme: this._getTheme(),
        data: () => fps,
      })
      fpsMonitor.on('destroy', () => raf.cancel.call(window, fpsId))
      this._fpsMonitor = fpsMonitor
    }
    _initMemory(el) {
      // メモリ使用量モニター作成
      const memoryMonitor = new LunaPerformanceMonitor(el, {
        title: '使用中の JS ヒープサイズ',
        unit: 'MB',
        color: this._getColor(),
        smooth: false,
        theme: this._getTheme(),
        data() {
          return (performance.memory.usedJSHeapSize / 1024 / 1024).toFixed(1)
        },
      })
      this._memoryMonitor = memoryMonitor
    }
    _initDomNodes(el) {
      // DOM ノード数モニター作成
      const domNodesMonitor = new LunaPerformanceMonitor(el, {
        title: 'DOM ノード数',
        color: this._getColor(),
        smooth: false,
        theme: this._getTheme(),
        data() {
          return document.body.getElementsByTagName('*').length
        },
      })
      this._domNodesMonitor = domNodesMonitor
    }
    _onThemeChange = (name) => {
      // テーマ変更時の色・テーマ再設定
      const fpsMonitor = this._fpsMonitor
      const domNodesMonitor = this._domNodesMonitor
      const memoryMonitor = this._memoryMonitor
      if (name === 'theme') {
        const theme = this._getTheme()
        fpsMonitor.setOption({
          color: this._getColor(),
          theme,
        })
        domNodesMonitor.setOption({
          color: this._getColor(),
          theme,
        })
        if (memoryMonitor) {
          memoryMonitor.setOption({
            color: this._getColor(),
            theme,
          })
        }
      }
    }
  }

  return new Monitor()
}