Skip to content

Commit de290d8

Browse files
author
Guillaume Chau
committed
fix(webpack dashboard): anazlyer sort on size types + performance improvements
1 parent a549d56 commit de290d8

File tree

7 files changed

+103
-90
lines changed

7 files changed

+103
-90
lines changed

packages/@vue/cli-ui-addon-webpack/src/components/DonutModule.vue

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
:transform="`translate(${size / 2}, ${size / 2})`"
2828
>
2929
<DonutModule
30-
v-for="module of module.children"
31-
v-if="isVisible(getRatio(module, ratio))"
32-
:key="module.id"
33-
:module="module"
30+
v-for="m of module.children"
31+
v-if="isVisible(getRatio(m, ratio))"
32+
:key="m.id"
33+
:module="m"
3434
:depth="depth + 1"
35+
:parent-module="module"
3536
:parent-ratio="ratio"
3637
:colors="colors"
3738
/>
@@ -55,6 +56,11 @@ export default {
5556
required: true
5657
},
5758
59+
parentModule: {
60+
type: Object,
61+
default: undefined
62+
},
63+
5864
depth: {
5965
type: Number,
6066
required: true
@@ -101,7 +107,7 @@ export default {
101107
},
102108
103109
rotation () {
104-
return this.module.previousSize[this.sizeField] / this.module.parent.size[this.sizeField] * this.parentRatio * 360
110+
return this.module.previousSize[this.sizeField] / this.parentModule.size[this.sizeField] * this.parentRatio * 360
105111
},
106112
107113
size () {
@@ -129,7 +135,7 @@ export default {
129135
130136
methods: {
131137
getRatio (module, parentRatio) {
132-
return module.size[this.sizeField] / module.parent.size[this.sizeField] * parentRatio
138+
return module.size[this.sizeField] / this.parentModule.size[this.sizeField] * parentRatio
133139
},
134140
135141
isVisible (ratio) {

packages/@vue/cli-ui-addon-webpack/src/components/WebpackAnalyzer.vue

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
v-for="(module, index) of currentTree.children"
7575
:key="module.id"
7676
:module="module"
77+
:parent-module="currentTree"
7778
:colors="getColors(index)"
7879
:depth="0"
7980
:parent-ratio="1"
@@ -144,7 +145,8 @@ export default {
144145
injection: {
145146
hoverModule: null
146147
},
147-
currentTree: null
148+
currentTree: null,
149+
currentParent: null
148150
}
149151
},
150152
@@ -209,6 +211,16 @@ export default {
209211
},
210212
211213
methods: {
214+
syncMode (mode) {
215+
Dashboard.methods.syncMode.call(this, mode)
216+
this.$watchSharedData(`org.vue.webpack.${mode}-stats-analyzer`, value => {
217+
this.$store.commit('analyzer', {
218+
mode,
219+
value
220+
})
221+
})
222+
},
223+
212224
getColors (index) {
213225
const list = colors[this.darkMode ? 'dark' : 'light']
214226
return list[index % list.length]
@@ -299,19 +311,21 @@ export default {
299311
300312
onDonutClick () {
301313
if (this.hoverModule && this.hoverModule.children.length) {
314+
this.currentParent = this.currentTree
302315
this.currentTree = this.hoverModule
303316
this.hoverModule = null
304317
}
305318
},
306319
307320
goToParent () {
308-
if (this.currentTree && this.currentTree.parent) {
309-
this.currentTree = this.currentTree.parent
321+
if (this.currentParent) {
322+
this.currentTree = this.currentParent
310323
}
311324
},
312325
313326
goToHome () {
314327
this.currentTree = this.rootTree
328+
this.currentParent = null
315329
}
316330
}
317331
}

packages/@vue/cli-ui-addon-webpack/src/store/index.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import Vuex from 'vuex'
22

33
import { buildSortedAssets } from '../util/assets'
4-
import { filterModules, buildSortedModules, buildDepModules, buildModulesTrees } from '../util/modules'
54

65
Vue.use(Vuex)
76

@@ -12,13 +11,16 @@ const store = new Vuex.Store({
1211
mode: 'serve',
1312
showModernBuild: true,
1413
serve: {
15-
stats: null
14+
stats: null,
15+
analyzer: {}
1616
},
1717
build: {
18-
stats: null
18+
stats: null,
19+
analyzer: {}
1920
},
2021
'build-modern': {
21-
stats: null
22+
stats: null,
23+
analyzer: {}
2224
}
2325
}
2426
},
@@ -37,12 +39,12 @@ const store = new Vuex.Store({
3739
assets: (state, getters) => (getters.stats && getters.stats.data.assets) || [],
3840
assetsSorted: (state, getters) => buildSortedAssets(getters.assets, getters.sizeField),
3941
assetsTotalSize: (state, getters) => getters.assetsSorted.filter(a => !a.secondary).reduce((total, asset) => total + asset.size, 0),
40-
rawModules: (state, getters) => (getters.stats && filterModules(getters.stats.data.modules)) || [],
41-
modules: (state, getters) => buildSortedModules(getters.rawModules, getters.sizeField),
42-
modulesTotalSize: (state, getters) => getters.modules.reduce((total, module) => total + module.size, 0),
43-
modulesTrees: (state, getters) => buildModulesTrees(getters.rawModules),
44-
depModules: (state, getters) => buildDepModules(getters.modules),
45-
depModulesTotalSize: (state, getters) => getters.depModules.reduce((total, module) => total + module.size, 0),
42+
modules: (state, getters) => (getters.stats && getters.stats.computed.modulesPerSizeType[getters.sizeField]) || {},
43+
modulesTotalSize: (state, getters) => getters.modules.modulesTotalSize || 0,
44+
analyzer: (state, getters) => state[getters.mode].analyzer[getters.sizeField],
45+
modulesTrees: (state, getters) => (getters.analyzer && getters.analyzer.modulesTrees) || [],
46+
depModules: (state, getters) => getters.modules.depModules || [],
47+
depModulesTotalSize: (state, getters) => getters.modules.depModulesTotalSize || 0,
4648
chunks: (state, getters) => (getters.stats && getters.stats.data.chunks) || []
4749
},
4850

@@ -61,7 +63,12 @@ const store = new Vuex.Store({
6163
},
6264

6365
stats (state, { mode, value }) {
64-
state[mode].stats = value
66+
state[mode].stats = Object.freeze(value)
67+
},
68+
69+
analyzer (state, { mode, value }) {
70+
console.log(value)
71+
state[mode].analyzer = Object.freeze(value)
6572
}
6673
}
6774
})

packages/@vue/cli-ui/package-lock.json

Lines changed: 0 additions & 57 deletions
This file was deleted.

packages/@vue/cli-ui/ui-defaults/tasks.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const path = require('path')
22
const fs = require('fs-extra')
3+
const { processStats } = require('./utils/stats')
34

45
module.exports = api => {
56
const { getSharedData, setSharedData, removeSharedData } = api.namespace('org.vue.webpack.')
@@ -73,7 +74,9 @@ module.exports = api => {
7374
// Stats are read from a file
7475
const statsFile = path.resolve(api.getCwd(), `./node_modules/.stats-${type}.json`)
7576
const value = await fs.readJson(statsFile)
76-
setSharedData(id, value)
77+
const { stats, analyzer } = processStats(value)
78+
setSharedData(id, stats)
79+
setSharedData(`${id}-analyzer`, analyzer)
7780
await fs.remove(statsFile)
7881
} else if (data.type === 'progress') {
7982
if (type === 'serve' || !modernMode) {

packages/@vue/cli-ui-addon-webpack/src/util/modules.js renamed to packages/@vue/cli-ui/ui-defaults/utils/modules.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ const getModulePath = function (identifier) {
22
return identifier.replace(/.*!/, '').replace(/\\/g, '/')
33
}
44

5-
export function filterModules (modules) {
5+
exports.filterModules = function (modules) {
66
return modules.filter(module => module.name.indexOf('(webpack)') === -1)
77
}
88

9-
export function buildSortedModules (modules, sizeField) {
9+
exports.buildSortedModules = function (modules, sizeField) {
1010
let list = modules.slice()
1111
if (list.length) {
1212
list = list.map(module => {
@@ -22,7 +22,7 @@ export function buildSortedModules (modules, sizeField) {
2222
return list
2323
}
2424

25-
export function buildDepModules (modules) {
25+
exports.buildDepModules = function (modules) {
2626
const deps = new Map()
2727
for (const module of modules) {
2828
const path = getModulePath(module.identifier)
@@ -66,7 +66,6 @@ export function buildDepModules (modules) {
6666
gzip: 400
6767
}
6868
fullPath: '/node_modules',
69-
parent: undefined,
7069
children: [
7170
{
7271
id: 'vuex',
@@ -86,14 +85,13 @@ export function buildDepModules (modules) {
8685
children: [
8786
...
8887
],
89-
parent: ...
9088
},
9189
...
9290
]
9391
}
9492
*/
9593

96-
export function buildModulesTrees (modules) {
94+
exports.buildModulesTrees = function (modules, sizeType) {
9795
const trees = {}
9896

9997
for (const module of modules) {
@@ -127,8 +125,7 @@ export function buildModulesTrees (modules) {
127125
gzip: 0
128126
},
129127
fullPath: fullPath.join('/'),
130-
children: {},
131-
parent: subtree
128+
children: {}
132129
}
133130
}
134131
child.size.stats += module.size.stats
@@ -149,22 +146,22 @@ export function buildModulesTrees (modules) {
149146
while ((keys = Object.keys(tree.children)).length !== 0 && keys.length === 1) {
150147
tree = tree.children[keys[0]]
151148
}
152-
walkTreeToSortChildren(tree)
149+
walkTreeToSortChildren(tree, sizeType)
153150
trees[n] = tree
154151
}
155152

156153
return trees
157154
}
158155

159-
function walkTreeToSortChildren (tree) {
156+
function walkTreeToSortChildren (tree, sizeType) {
160157
let size = {
161158
stats: 0,
162159
parsed: 0,
163160
gzip: 0
164161
}
165162
tree.children = Object.keys(tree.children).map(
166163
key => tree.children[key]
167-
).sort((a, b) => b.size.stats - a.size.stats)
164+
).sort((a, b) => b.size[sizeType] - a.size[sizeType])
168165
for (const child of tree.children) {
169166
child.previousSize = {
170167
stats: size.stats,
@@ -174,6 +171,6 @@ function walkTreeToSortChildren (tree) {
174171
size.stats += child.size.stats
175172
size.parsed += child.size.parsed
176173
size.gzip += child.size.gzip
177-
walkTreeToSortChildren(child)
174+
walkTreeToSortChildren(child, sizeType)
178175
}
179176
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const ModulesUtils = require('./modules')
2+
3+
const sizeTypes = ['stats', 'parsed', 'gzip']
4+
5+
exports.processStats = function (stats) {
6+
const rawModules = ModulesUtils.filterModules(stats.data.modules)
7+
8+
const modulesPerSizeType = {}
9+
const analyzer = {}
10+
for (const sizeType of sizeTypes) {
11+
const modules = ModulesUtils.buildSortedModules(rawModules, sizeType)
12+
const modulesTotalSize = modules.reduce((total, module) => total + module.size, 0)
13+
const depModules = ModulesUtils.buildDepModules(modules)
14+
const depModulesTotalSize = depModules.reduce((total, module) => total + module.size, 0)
15+
modulesPerSizeType[sizeType] = {
16+
modulesTotalSize,
17+
depModules,
18+
depModulesTotalSize
19+
}
20+
21+
const modulesTrees = ModulesUtils.buildModulesTrees(rawModules, sizeType)
22+
analyzer[sizeType] = {
23+
modulesTrees
24+
}
25+
}
26+
27+
stats = {
28+
data: {
29+
errors: stats.data.errors,
30+
warnings: stats.data.warnings,
31+
assets: stats.data.assets,
32+
chunks: stats.data.chunks
33+
},
34+
computed: {
35+
modulesPerSizeType
36+
}
37+
}
38+
39+
return {
40+
stats,
41+
analyzer
42+
}
43+
}

0 commit comments

Comments
 (0)