@bundle-stats/utils 4.7.5-alpha.0 → 4.7.5-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browsertime/metrics.js +22 -22
- package/lib/browsertime/metrics.js.map +1 -1
- package/lib/config/index.js +1 -2
- package/lib/config/index.js.map +1 -1
- package/lib/config/metric-types.js +28 -0
- package/lib/config/metric-types.js.map +1 -0
- package/lib/constants.js +9 -19
- package/lib/constants.js.map +1 -1
- package/lib/lighthouse/metrics.js +13 -13
- package/lib/lighthouse/metrics.js.map +1 -1
- package/lib/report/add-row-metric-data.js +2 -2
- package/lib/report/add-row-metric-data.js.map +1 -1
- package/lib/report/create.js.map +1 -1
- package/lib/utils/component-links.js +1 -7
- package/lib/utils/component-links.js.map +1 -1
- package/lib/utils/delta.js +29 -26
- package/lib/utils/delta.js.map +1 -1
- package/lib/utils/metrics.js +47 -29
- package/lib/utils/metrics.js.map +1 -1
- package/lib/webpack/compare.js +11 -11
- package/lib/webpack/compare.js.map +1 -1
- package/lib/webpack/metrics.js +25 -24
- package/lib/webpack/metrics.js.map +1 -1
- package/lib-esm/browsertime/metrics.js +22 -22
- package/lib-esm/browsertime/metrics.js.map +1 -1
- package/lib-esm/config/index.js +1 -2
- package/lib-esm/config/index.js.map +1 -1
- package/lib-esm/config/metric-types.js +25 -0
- package/lib-esm/config/metric-types.js.map +1 -0
- package/lib-esm/constants.js +8 -18
- package/lib-esm/constants.js.map +1 -1
- package/lib-esm/lighthouse/metrics.js +13 -13
- package/lib-esm/lighthouse/metrics.js.map +1 -1
- package/lib-esm/report/add-row-metric-data.js +2 -2
- package/lib-esm/report/add-row-metric-data.js.map +1 -1
- package/lib-esm/report/create.js.map +1 -1
- package/lib-esm/utils/component-links.js +1 -7
- package/lib-esm/utils/component-links.js.map +1 -1
- package/lib-esm/utils/delta.js +29 -26
- package/lib-esm/utils/delta.js.map +1 -1
- package/lib-esm/utils/metrics.js +44 -27
- package/lib-esm/utils/metrics.js.map +1 -1
- package/lib-esm/webpack/compare.js +4 -4
- package/lib-esm/webpack/compare.js.map +1 -1
- package/lib-esm/webpack/metrics.js +25 -24
- package/lib-esm/webpack/metrics.js.map +1 -1
- package/package.json +5 -5
- package/src/browsertime/metrics.js +22 -22
- package/src/config/index.js +1 -2
- package/src/config/metric-types.ts +25 -0
- package/src/constants.ts +64 -28
- package/src/lighthouse/metrics.js +13 -15
- package/src/report/add-row-metric-data.ts +3 -2
- package/src/report/create.ts +1 -1
- package/src/utils/component-links.ts +1 -7
- package/src/utils/delta.ts +91 -0
- package/src/utils/metrics.ts +81 -0
- package/src/webpack/compare.js +19 -12
- package/src/webpack/{metrics.js → metrics.ts} +30 -29
- package/types/browsertime/metrics.d.ts +43 -23
- package/types/config/index.d.ts +1 -2
- package/types/config/metric-types.d.ts +2 -0
- package/types/constants.d.ts +24 -22
- package/types/lighthouse/metrics.d.ts +25 -17
- package/types/report/add-row-metric-data.d.ts +4 -3
- package/types/utils/component-links.d.ts +0 -4
- package/types/utils/delta.d.ts +4 -6
- package/types/utils/metrics.d.ts +4 -3
- package/types/webpack/metrics.d.ts +7 -153
- package/types/webpack/utils.d.ts +1 -1
- package/lib/config/delta.js +0 -13
- package/lib/config/delta.js.map +0 -1
- package/lib/config/metrics.js +0 -32
- package/lib/config/metrics.js.map +0 -1
- package/lib-esm/config/delta.js +0 -10
- package/lib-esm/config/delta.js.map +0 -1
- package/lib-esm/config/metrics.js +0 -29
- package/lib-esm/config/metrics.js.map +0 -1
- package/src/config/delta.js +0 -11
- package/src/config/metrics.js +0 -31
- package/src/utils/delta.js +0 -94
- package/src/utils/metrics.js +0 -92
- package/types/config/delta.d.ts +0 -9
- package/types/config/metrics.d.ts +0 -6
package/src/constants.ts
CHANGED
|
@@ -12,39 +12,73 @@ export enum InsightType {
|
|
|
12
12
|
WARNING = 'warning',
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Generic metric type names
|
|
17
|
+
*/
|
|
18
|
+
export enum MetricTypes {
|
|
19
|
+
Numeric = 'METRIC_TYPE_NUMERIC',
|
|
20
|
+
Score = 'METRIC_TYPE_SCORE',
|
|
21
|
+
FileSize = 'METRIC_TYPE_FILE_SIZE',
|
|
22
|
+
Duration = 'METRIC_TYPE_DURATION',
|
|
23
|
+
Percentage = 'METRIC_TYPE_PERCENTAGE',
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Metric type base configuration
|
|
28
|
+
*/
|
|
23
29
|
export interface MetricTypeConfig {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Increased values are regressions, decreased values are improvements
|
|
32
|
+
*/
|
|
33
|
+
biggerIsBetter?: boolean | null;
|
|
34
|
+
/**
|
|
35
|
+
* Value formatter
|
|
36
|
+
*/
|
|
37
|
+
formatter: (value: number | null) => string;
|
|
27
38
|
}
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Source metric configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface MetricConfig {
|
|
44
|
+
label: string;
|
|
45
|
+
type: MetricTypes;
|
|
46
|
+
description?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Documentation URL
|
|
49
|
+
*/
|
|
50
|
+
url?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Positive delta values are regressions and negative delta values are improvements
|
|
53
|
+
* overrides MetricTypeConfig['biggerIsBetter']
|
|
54
|
+
*/
|
|
55
|
+
biggerIsBetter?: MetricTypeConfig['biggerIsBetter'];
|
|
56
|
+
/**
|
|
57
|
+
* Do not show the delta
|
|
58
|
+
*/
|
|
59
|
+
skipDelta?: boolean;
|
|
32
60
|
}
|
|
33
61
|
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
export type Metric = MetricTypeConfig & MetricConfig;
|
|
63
|
+
|
|
64
|
+
export type MetricRunInfoDeltaType =
|
|
65
|
+
| 'HIGH_NEGATIVE'
|
|
66
|
+
| 'NEGATIVE'
|
|
67
|
+
| 'LOW_NEGATIVE'
|
|
68
|
+
| 'NO_CHANGE'
|
|
69
|
+
| 'LOW_POSITIVE'
|
|
70
|
+
| 'POSITIVE'
|
|
71
|
+
| 'HIGH_POSITIVE';
|
|
43
72
|
|
|
44
73
|
export interface MetricRun {
|
|
45
74
|
value: number;
|
|
46
75
|
}
|
|
47
76
|
|
|
77
|
+
export interface MetricRunDelta {
|
|
78
|
+
delta: number;
|
|
79
|
+
deltaPercentage: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
48
82
|
export interface MetricRunInfo {
|
|
49
83
|
value: number;
|
|
50
84
|
displayValue: string;
|
|
@@ -53,6 +87,7 @@ export interface MetricRunInfo {
|
|
|
53
87
|
deltaType?: MetricRunInfoDeltaType;
|
|
54
88
|
displayDelta?: string;
|
|
55
89
|
displayDeltaPercentage?: string;
|
|
90
|
+
regression?: boolean | null;
|
|
56
91
|
}
|
|
57
92
|
|
|
58
93
|
export type JobSection<T = object> = Record<Source, T>;
|
|
@@ -77,6 +112,7 @@ export interface JobInsight<T = object> {
|
|
|
77
112
|
|
|
78
113
|
export interface JobInsightAssetsSizeTotalData {
|
|
79
114
|
md: string;
|
|
115
|
+
text: string;
|
|
80
116
|
info: MetricRunInfo;
|
|
81
117
|
}
|
|
82
118
|
export type JobInsightDuplicatePackagesData = Record<string, Array<string>>;
|
|
@@ -160,10 +196,10 @@ export interface BrowsertimeSource {
|
|
|
160
196
|
info?: {
|
|
161
197
|
browsertime: {
|
|
162
198
|
version: string;
|
|
163
|
-
}
|
|
199
|
+
};
|
|
164
200
|
timestamp: string;
|
|
165
201
|
url: string;
|
|
166
|
-
}
|
|
202
|
+
};
|
|
167
203
|
statistics?: {
|
|
168
204
|
timings: {
|
|
169
205
|
firstPaint: BrowsertimeSourceMetric;
|
|
@@ -179,12 +215,12 @@ export interface BrowsertimeSource {
|
|
|
179
215
|
redirectionTime: BrowsertimeSourceMetric;
|
|
180
216
|
serverConnectionTime: BrowsertimeSourceMetric;
|
|
181
217
|
serverResponseTime: BrowsertimeSourceMetric;
|
|
182
|
-
}
|
|
218
|
+
};
|
|
183
219
|
paintTiming: {
|
|
184
220
|
'first-contentful-paint': BrowsertimeSourceMetric;
|
|
185
|
-
}
|
|
221
|
+
};
|
|
186
222
|
rumSpeedIndex: BrowsertimeSourceMetric;
|
|
187
|
-
}
|
|
223
|
+
};
|
|
188
224
|
visualmetrics: {
|
|
189
225
|
FirstVisualChange: BrowsertimeSourceMetric;
|
|
190
226
|
LastVisualChange: BrowsertimeSourceMetric;
|
|
@@ -193,8 +229,8 @@ export interface BrowsertimeSource {
|
|
|
193
229
|
VisualComplete85: BrowsertimeSourceMetric;
|
|
194
230
|
VisualComplete95: BrowsertimeSourceMetric;
|
|
195
231
|
VisualComplete99: BrowsertimeSourceMetric;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
232
|
+
};
|
|
233
|
+
};
|
|
198
234
|
}
|
|
199
235
|
|
|
200
236
|
export interface BrowsertimeMetrics {
|
|
@@ -1,55 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
METRIC_TYPE_SCORE, METRIC_TYPE_DURATION, METRIC_TYPE_FILE_SIZE, METRIC_TYPE_NUMERIC,
|
|
3
|
-
} from '../config/metrics';
|
|
1
|
+
import { MetricTypes } from '../constants';
|
|
4
2
|
|
|
5
3
|
export const metrics = {
|
|
6
4
|
score: {
|
|
7
5
|
label: 'Score',
|
|
8
|
-
type:
|
|
6
|
+
type: MetricTypes.Score,
|
|
9
7
|
},
|
|
10
8
|
performanceScore: {
|
|
11
9
|
label: 'Performance',
|
|
12
|
-
type:
|
|
10
|
+
type: MetricTypes.Score,
|
|
13
11
|
},
|
|
14
12
|
accessibilityScore: {
|
|
15
13
|
label: 'Accessibility',
|
|
16
|
-
type:
|
|
14
|
+
type: MetricTypes.Score,
|
|
17
15
|
},
|
|
18
16
|
bestPracticesScore: {
|
|
19
17
|
label: 'Best Practices',
|
|
20
|
-
type:
|
|
18
|
+
type: MetricTypes.Score,
|
|
21
19
|
},
|
|
22
20
|
seoScore: {
|
|
23
21
|
label: 'SEO',
|
|
24
|
-
type:
|
|
22
|
+
type: MetricTypes.Score,
|
|
25
23
|
},
|
|
26
24
|
pwaScore: {
|
|
27
25
|
label: 'PWA',
|
|
28
|
-
type:
|
|
26
|
+
type: MetricTypes.Score,
|
|
29
27
|
},
|
|
30
28
|
|
|
31
29
|
speedIndex: {
|
|
32
30
|
label: 'Perceptual Speed Index',
|
|
33
|
-
type:
|
|
31
|
+
type: MetricTypes.Duration,
|
|
34
32
|
},
|
|
35
33
|
firstMeaningfulPaint: {
|
|
36
34
|
label: 'First Meaningful Paint',
|
|
37
|
-
type:
|
|
35
|
+
type: MetricTypes.Duration,
|
|
38
36
|
},
|
|
39
37
|
timeToFirstByte: {
|
|
40
38
|
label: 'Time To First Byte',
|
|
41
|
-
type:
|
|
39
|
+
type: MetricTypes.Duration,
|
|
42
40
|
},
|
|
43
41
|
firstInteractive: {
|
|
44
42
|
label: 'First Interactive',
|
|
45
|
-
type:
|
|
43
|
+
type: MetricTypes.Duration,
|
|
46
44
|
},
|
|
47
45
|
totalByteWeight: {
|
|
48
46
|
label: 'Total Weight',
|
|
49
|
-
type:
|
|
47
|
+
type: MetricTypes.FileSize,
|
|
50
48
|
},
|
|
51
49
|
domSize: {
|
|
52
50
|
label: 'DOM Size',
|
|
53
|
-
type:
|
|
51
|
+
type: MetricTypes.Numeric,
|
|
54
52
|
},
|
|
55
53
|
};
|
|
@@ -3,6 +3,7 @@ import get from 'lodash/get';
|
|
|
3
3
|
import { getGlobalMetricType, getMetricRunInfo } from '../utils/metrics';
|
|
4
4
|
import { getMetricChanged } from './get-metric-changed';
|
|
5
5
|
import * as types from './types';
|
|
6
|
+
import { MetricTypes } from '../constants';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Add row metric diff data
|
|
@@ -15,7 +16,7 @@ export const getAddRowMetricData = (metricType?: string) => (row: types.ReportRo
|
|
|
15
16
|
// - if the key is not matching an existing metric, use the default metricType
|
|
16
17
|
const metric = getGlobalMetricType(
|
|
17
18
|
key,
|
|
18
|
-
typeof metricType === 'string'
|
|
19
|
+
typeof metricType === 'string' ? (metricType as MetricTypes) : undefined, // explicit, avoid passing of map cb params
|
|
19
20
|
);
|
|
20
21
|
const { biggerIsBetter, label } = metric;
|
|
21
22
|
|
|
@@ -28,7 +29,7 @@ export const getAddRowMetricData = (metricType?: string) => (row: types.ReportRo
|
|
|
28
29
|
metric,
|
|
29
30
|
run.value,
|
|
30
31
|
// Get baseline value only if not the latest run
|
|
31
|
-
|
|
32
|
+
index + 1 < runs.length ? get(runs, [index + 1, 'value'], 0) : undefined,
|
|
32
33
|
);
|
|
33
34
|
|
|
34
35
|
return {
|
package/src/report/create.ts
CHANGED
|
@@ -44,7 +44,7 @@ export const createReport = (jobs: Array<Job>): Report => {
|
|
|
44
44
|
return Object.assign(data, { label: metric.label });
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
summary[sourceId] = summaryEntries;
|
|
47
|
+
summary[sourceId] = summaryEntries as any;
|
|
48
48
|
}, {});
|
|
49
49
|
|
|
50
50
|
const sectionsData = webpack.compare(jobs);
|
|
@@ -377,13 +377,7 @@ export const METRIC_COMPONENT_LINKS = new Map([
|
|
|
377
377
|
['webpack.totalSizeByTypeALL', { link: TOTALS }],
|
|
378
378
|
['webpack.totalInitialSizeJS', { link: BUNDLE_ASSETS_INITIAL_JS }],
|
|
379
379
|
['webpack.totalInitialSizeCSS', { link: BUNDLE_ASSETS_INITIAL_CSS }],
|
|
380
|
-
[
|
|
381
|
-
'webpack.cacheInvalidation',
|
|
382
|
-
{
|
|
383
|
-
link: BUNDLE_ASSETS_CACHE_INVALIDATION,
|
|
384
|
-
showDelta: false,
|
|
385
|
-
},
|
|
386
|
-
],
|
|
380
|
+
['webpack.cacheInvalidation', { link: BUNDLE_ASSETS_CACHE_INVALIDATION }],
|
|
387
381
|
['webpack.assetCount', { link: BUNDLE_ASSETS_COUNT }],
|
|
388
382
|
['webpack.chunkCount', { link: BUNDLE_ASSETS_CHUNK_COUNT }],
|
|
389
383
|
['webpack.moduleCount', { link: BUNDLE_MODULES }],
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import round from 'lodash/round';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
MetricRun,
|
|
5
|
+
MetricRunDelta,
|
|
6
|
+
MetricRunInfoDeltaType,
|
|
7
|
+
MetricTypeConfig,
|
|
8
|
+
} from '../constants';
|
|
9
|
+
|
|
10
|
+
export function getDelta(baseline?: MetricRun | null, current?: MetricRun | null): MetricRunDelta {
|
|
11
|
+
const baselineValue = baseline?.value || 0;
|
|
12
|
+
const currentValue = current?.value || 0;
|
|
13
|
+
|
|
14
|
+
if (baselineValue === currentValue) {
|
|
15
|
+
return {
|
|
16
|
+
delta: 0,
|
|
17
|
+
deltaPercentage: 0,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (baselineValue === 0) {
|
|
22
|
+
return {
|
|
23
|
+
delta: currentValue,
|
|
24
|
+
deltaPercentage: 100,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
delta: currentValue - baselineValue,
|
|
30
|
+
deltaPercentage: round((currentValue / baselineValue) * 100 - 100, 8),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Format delta output
|
|
36
|
+
*/
|
|
37
|
+
export function formatDelta(value: number, formatter: MetricTypeConfig['formatter']): string {
|
|
38
|
+
let sign = '';
|
|
39
|
+
|
|
40
|
+
if (value > 0) {
|
|
41
|
+
sign = '+';
|
|
42
|
+
} else if (value < 0) {
|
|
43
|
+
sign = '-';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let absValue = Math.abs(value);
|
|
47
|
+
|
|
48
|
+
if (absValue > 0 && absValue < 0.01) {
|
|
49
|
+
sign = `~${sign}`;
|
|
50
|
+
absValue = 0.01;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (absValue > 0.01) {
|
|
54
|
+
absValue = round(absValue, 2);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return `${sign}${formatter(absValue)}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get delta type
|
|
62
|
+
*/
|
|
63
|
+
export function getDeltaType(
|
|
64
|
+
deltaPercentageValue: number,
|
|
65
|
+
biggerIsBetter?: MetricTypeConfig['biggerIsBetter'],
|
|
66
|
+
): MetricRunInfoDeltaType {
|
|
67
|
+
if (deltaPercentageValue < -50) {
|
|
68
|
+
return biggerIsBetter ? 'HIGH_NEGATIVE' : 'HIGH_POSITIVE';
|
|
69
|
+
}
|
|
70
|
+
if (deltaPercentageValue < -5) {
|
|
71
|
+
return biggerIsBetter ? 'NEGATIVE' : 'POSITIVE';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (deltaPercentageValue < 0) {
|
|
75
|
+
return biggerIsBetter ? 'LOW_NEGATIVE' : 'LOW_POSITIVE';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (deltaPercentageValue === 0) {
|
|
79
|
+
return 'NO_CHANGE';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (deltaPercentageValue <= 5) {
|
|
83
|
+
return biggerIsBetter ? 'LOW_POSITIVE' : 'LOW_NEGATIVE';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (deltaPercentageValue <= 50) {
|
|
87
|
+
return biggerIsBetter ? 'POSITIVE' : 'NEGATIVE';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return biggerIsBetter ? 'HIGH_POSITIVE' : 'HIGH_NEGATIVE';
|
|
91
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
|
|
3
|
+
import { MetricRunInfo, Metric, MetricTypes, MetricConfig, MetricTypeConfig } from '../constants';
|
|
4
|
+
import { METRIC_TYPE_CONFIGS } from '../config';
|
|
5
|
+
import { metrics as webpackMetricTypes } from '../webpack/metrics';
|
|
6
|
+
import { metrics as lighthouseMetricTypes } from '../lighthouse/metrics';
|
|
7
|
+
import { metrics as browsertimeMeticTypes } from '../browsertime/metrics';
|
|
8
|
+
import { formatPercentage } from './format';
|
|
9
|
+
import { formatDelta, getDelta, getDeltaType } from './delta';
|
|
10
|
+
|
|
11
|
+
export function createGetMetricType(metrics: Record<string, unknown>) {
|
|
12
|
+
return function getMetricType(key: string, type?: MetricTypes): Metric {
|
|
13
|
+
const metric = get(metrics, key) as MetricConfig;
|
|
14
|
+
|
|
15
|
+
if (metric?.type) {
|
|
16
|
+
return {
|
|
17
|
+
...METRIC_TYPE_CONFIGS[metric.type],
|
|
18
|
+
...metric,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const resolvedType = type || MetricTypes.Numeric;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...METRIC_TYPE_CONFIGS[resolvedType],
|
|
26
|
+
type: resolvedType,
|
|
27
|
+
label: key,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getGlobalMetricType(key: string, type?: MetricTypes): Metric {
|
|
33
|
+
const getMetricType = createGetMetricType({
|
|
34
|
+
webpack: webpackMetricTypes,
|
|
35
|
+
lighthouse: lighthouseMetricTypes,
|
|
36
|
+
browsertime: browsertimeMeticTypes,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return getMetricType(key, type);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getMetricRunInfo(
|
|
43
|
+
metricType: MetricTypeConfig,
|
|
44
|
+
current: number,
|
|
45
|
+
baseline?: number,
|
|
46
|
+
): MetricRunInfo {
|
|
47
|
+
const { formatter, biggerIsBetter } = metricType;
|
|
48
|
+
|
|
49
|
+
const runInfo = {
|
|
50
|
+
value: current,
|
|
51
|
+
displayValue: formatter(current),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Skip computing delta fields when the baseline is missing
|
|
55
|
+
if (typeof baseline === 'undefined') {
|
|
56
|
+
return runInfo;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const { delta, deltaPercentage } = getDelta({ value: baseline }, { value: current });
|
|
60
|
+
|
|
61
|
+
// Resolve regression/improvement flag
|
|
62
|
+
let regression;
|
|
63
|
+
|
|
64
|
+
if (biggerIsBetter === null) {
|
|
65
|
+
regression = null;
|
|
66
|
+
} else if ((biggerIsBetter === true && delta > 0) || (biggerIsBetter === false && delta < 0)) {
|
|
67
|
+
regression = false;
|
|
68
|
+
} else if ((biggerIsBetter === false && delta > 0) || (biggerIsBetter === true && delta < 0)) {
|
|
69
|
+
regression = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
...runInfo,
|
|
74
|
+
delta,
|
|
75
|
+
deltaPercentage,
|
|
76
|
+
displayDelta: formatDelta(delta, formatter),
|
|
77
|
+
displayDeltaPercentage: formatDelta(deltaPercentage, formatPercentage),
|
|
78
|
+
deltaType: getDeltaType(deltaPercentage, biggerIsBetter),
|
|
79
|
+
regression,
|
|
80
|
+
};
|
|
81
|
+
}
|
package/src/webpack/compare.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MetricTypes } from '../constants';
|
|
2
2
|
import { compareMetrics } from '../report/compare-metrics';
|
|
3
3
|
import {
|
|
4
4
|
SECTION_WEBPACK_STATS,
|
|
@@ -18,9 +18,8 @@ import { selectors } from './selectors';
|
|
|
18
18
|
*
|
|
19
19
|
* @return {Object[]} Compared stats metrics
|
|
20
20
|
*/
|
|
21
|
-
const compareStats = (jobs, rowTransformers) =>
|
|
22
|
-
jobs, selectors.stats, undefined, rowTransformers
|
|
23
|
-
);
|
|
21
|
+
const compareStats = (jobs, rowTransformers) =>
|
|
22
|
+
compareMetrics(jobs, selectors.stats, undefined, rowTransformers);
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* Compare size metrics
|
|
@@ -30,7 +29,8 @@ const compareStats = (jobs, rowTransformers) => compareMetrics(
|
|
|
30
29
|
*
|
|
31
30
|
* @return {Object[]} Compared size metrics
|
|
32
31
|
*/
|
|
33
|
-
const compareSizes = (jobs, rowTransformers) =>
|
|
32
|
+
const compareSizes = (jobs, rowTransformers) =>
|
|
33
|
+
compareMetrics(jobs, selectors.sizes, undefined, rowTransformers);
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Compare asset metrics
|
|
@@ -40,7 +40,8 @@ const compareSizes = (jobs, rowTransformers) => compareMetrics(jobs, selectors.s
|
|
|
40
40
|
*
|
|
41
41
|
* @return {Object[]} Compared asset metrics
|
|
42
42
|
*/
|
|
43
|
-
const compareAssets = (jobs, rowTransformers) =>
|
|
43
|
+
const compareAssets = (jobs, rowTransformers) =>
|
|
44
|
+
compareMetrics(jobs, selectors.assets, MetricTypes.FileSize, rowTransformers);
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* Compare all modules
|
|
@@ -49,7 +50,8 @@ const compareAssets = (jobs, rowTransformers) => compareMetrics(jobs, selectors.
|
|
|
49
50
|
* @param {Array<Function>} [rowTransformers]
|
|
50
51
|
* @return {Object[]} Compared module metrics
|
|
51
52
|
*/
|
|
52
|
-
const compareModules = (jobs, rowTransformers) =>
|
|
53
|
+
const compareModules = (jobs, rowTransformers) =>
|
|
54
|
+
compareMetrics(jobs, selectors.modules, MetricTypes.FileSize, rowTransformers);
|
|
53
55
|
|
|
54
56
|
/**
|
|
55
57
|
* Compare package metrics
|
|
@@ -59,7 +61,8 @@ const compareModules = (jobs, rowTransformers) => compareMetrics(jobs, selectors
|
|
|
59
61
|
*
|
|
60
62
|
* @return {Object[]} Compared package metrics
|
|
61
63
|
*/
|
|
62
|
-
const comparePackages = (jobs, rowTransformers) =>
|
|
64
|
+
const comparePackages = (jobs, rowTransformers) =>
|
|
65
|
+
compareMetrics(jobs, selectors.packages, MetricTypes.FileSize, rowTransformers);
|
|
63
66
|
|
|
64
67
|
export const compareBySection = {
|
|
65
68
|
[SECTION_WEBPACK_STATS]: compareStats,
|
|
@@ -75,7 +78,11 @@ export const compareBySection = {
|
|
|
75
78
|
* @param {Object[]} jobs - List of jobs to compare
|
|
76
79
|
* @return {Object} Compared metrics by section
|
|
77
80
|
*/
|
|
78
|
-
export const compare = (jobs) =>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
export const compare = (jobs) =>
|
|
82
|
+
SECTIONS.reduce(
|
|
83
|
+
(agg, sectionId) => ({
|
|
84
|
+
...agg,
|
|
85
|
+
[sectionId]: compareBySection[sectionId](jobs),
|
|
86
|
+
}),
|
|
87
|
+
{},
|
|
88
|
+
);
|
|
@@ -1,115 +1,116 @@
|
|
|
1
|
-
import {
|
|
2
|
-
METRIC_TYPE_FILE_SIZE,
|
|
3
|
-
METRIC_TYPE_NUMERIC,
|
|
4
|
-
METRIC_TYPE_PERCENTAGE,
|
|
5
|
-
} from '../config/metrics';
|
|
6
1
|
import { FILE_TYPE_LABELS } from '../config/file-types';
|
|
7
2
|
import { Metric } from './types';
|
|
3
|
+
import { MetricTypes, MetricConfig } from '../constants';
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
type WebpackMetrics = Partial<Record<Metric, MetricConfig>> & {
|
|
6
|
+
sizes: Partial<Record<Metric, MetricConfig>>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const metrics: WebpackMetrics = {
|
|
10
10
|
[Metric.BUNDLE_SIZE]: {
|
|
11
11
|
label: 'Bundle Size',
|
|
12
12
|
description: 'The total file size of the assets generated or processed by the bundler',
|
|
13
13
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
14
|
-
type:
|
|
14
|
+
type: MetricTypes.FileSize,
|
|
15
15
|
},
|
|
16
16
|
[Metric.INITIAL_SIZE_JS]: {
|
|
17
17
|
label: 'Initial JS',
|
|
18
18
|
description: 'The total file size of the JavaScript initial chunks',
|
|
19
19
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
20
|
-
type:
|
|
20
|
+
type: MetricTypes.FileSize,
|
|
21
21
|
},
|
|
22
22
|
[Metric.INITIAL_SIZE_CSS]: {
|
|
23
23
|
label: 'Initial CSS',
|
|
24
24
|
description: 'The total file size of the CSS initial chunks',
|
|
25
25
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
26
|
-
type:
|
|
26
|
+
type: MetricTypes.FileSize,
|
|
27
27
|
},
|
|
28
28
|
[Metric.CACHE_INVALIDATION]: {
|
|
29
29
|
label: 'Cache Invalidation',
|
|
30
30
|
description:
|
|
31
31
|
'The ratio between the total of the changed assets and the total file size(Bundle Size)',
|
|
32
32
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
33
|
-
type:
|
|
34
|
-
biggerIsBetter:
|
|
33
|
+
type: MetricTypes.Percentage,
|
|
34
|
+
biggerIsBetter: null,
|
|
35
|
+
skipDelta: true,
|
|
35
36
|
},
|
|
36
37
|
[Metric.CHUNK_COUNT]: {
|
|
37
38
|
label: 'Chunks',
|
|
38
39
|
description: 'The total number of chunks generated by the bundler',
|
|
39
40
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
40
|
-
type:
|
|
41
|
-
biggerIsBetter:
|
|
41
|
+
type: MetricTypes.Numeric,
|
|
42
|
+
biggerIsBetter: null,
|
|
42
43
|
},
|
|
43
44
|
[Metric.ASSET_COUNT]: {
|
|
44
45
|
label: 'Assets',
|
|
45
46
|
description: 'Total number of assets generated or produced by the bundler',
|
|
46
47
|
url: 'https://relative-ci.com/documentation/metrics-and-data#assets',
|
|
47
|
-
type:
|
|
48
|
-
biggerIsBetter:
|
|
48
|
+
type: MetricTypes.Numeric,
|
|
49
|
+
biggerIsBetter: null,
|
|
49
50
|
},
|
|
50
51
|
[Metric.MODULE_COUNT]: {
|
|
51
52
|
label: 'Modules',
|
|
52
53
|
description: 'The total number of bundled modules',
|
|
53
54
|
url: 'https://relative-ci.com/documentation/metrics-and-data#modules-1',
|
|
54
|
-
type:
|
|
55
|
-
biggerIsBetter:
|
|
55
|
+
type: MetricTypes.Numeric,
|
|
56
|
+
biggerIsBetter: null,
|
|
56
57
|
},
|
|
57
58
|
[Metric.DUPLICATE_MODULES_COUNT]: {
|
|
58
59
|
label: 'Duplicate Modules',
|
|
59
60
|
description: 'The total number of modules that belong to more than one chunk',
|
|
60
61
|
url: 'https://relative-ci.com/documentation/metrics-and-data#modules-1',
|
|
61
|
-
type:
|
|
62
|
-
biggerIsBetter:
|
|
62
|
+
type: MetricTypes.Numeric,
|
|
63
|
+
biggerIsBetter: null,
|
|
63
64
|
},
|
|
64
65
|
[Metric.DUPLICATE_CODE]: {
|
|
65
66
|
label: 'Duplicate Code',
|
|
66
67
|
description: 'The percentage of total duplicate module size from the total module size',
|
|
67
68
|
url: 'https://relative-ci.com/documentation/metrics-and-data#modules-1',
|
|
68
|
-
type:
|
|
69
|
+
type: MetricTypes.Percentage,
|
|
69
70
|
biggerIsBetter: false,
|
|
70
71
|
},
|
|
71
72
|
[Metric.PACKAGE_COUNT]: {
|
|
72
73
|
label: 'Packages',
|
|
73
74
|
description: 'The total number of bundled packages',
|
|
74
75
|
url: 'https://relative-ci.com/documentation/metrics-and-data#packages',
|
|
75
|
-
type:
|
|
76
|
+
type: MetricTypes.Numeric,
|
|
76
77
|
biggerIsBetter: false,
|
|
77
78
|
},
|
|
78
79
|
[Metric.DUPLICATE_PACKAGES_COUNT]: {
|
|
79
80
|
label: 'Duplicate Packages',
|
|
80
81
|
description: 'The total number of duplicate packages',
|
|
81
82
|
url: 'https://relative-ci.com/documentation/metrics-and-data#packages',
|
|
82
|
-
type:
|
|
83
|
+
type: MetricTypes.Numeric,
|
|
83
84
|
biggerIsBetter: false,
|
|
84
85
|
},
|
|
85
86
|
sizes: {
|
|
86
87
|
[Metric.TOTAL_SIZE_JS]: {
|
|
87
88
|
label: FILE_TYPE_LABELS.JS,
|
|
88
|
-
type:
|
|
89
|
+
type: MetricTypes.FileSize,
|
|
89
90
|
},
|
|
90
91
|
[Metric.TOTAL_SIZE_CSS]: {
|
|
91
92
|
label: FILE_TYPE_LABELS.CSS,
|
|
92
|
-
type:
|
|
93
|
+
type: MetricTypes.FileSize,
|
|
93
94
|
},
|
|
94
95
|
[Metric.TOTAL_SIZE_IMG]: {
|
|
95
96
|
label: FILE_TYPE_LABELS.IMG,
|
|
96
|
-
type:
|
|
97
|
+
type: MetricTypes.FileSize,
|
|
97
98
|
},
|
|
98
99
|
[Metric.TOTAL_SIZE_MEDIA]: {
|
|
99
100
|
label: FILE_TYPE_LABELS.MEDIA,
|
|
100
|
-
type:
|
|
101
|
+
type: MetricTypes.FileSize,
|
|
101
102
|
},
|
|
102
103
|
[Metric.TOTAL_SIZE_FONT]: {
|
|
103
104
|
label: FILE_TYPE_LABELS.FONT,
|
|
104
|
-
type:
|
|
105
|
+
type: MetricTypes.FileSize,
|
|
105
106
|
},
|
|
106
107
|
[Metric.TOTAL_SIZE_HTML]: {
|
|
107
108
|
label: FILE_TYPE_LABELS.HTML,
|
|
108
|
-
type:
|
|
109
|
+
type: MetricTypes.FileSize,
|
|
109
110
|
},
|
|
110
111
|
[Metric.TOTAL_SIZE_OTHER]: {
|
|
111
112
|
label: FILE_TYPE_LABELS.OTHER,
|
|
112
|
-
type:
|
|
113
|
+
type: MetricTypes.FileSize,
|
|
113
114
|
},
|
|
114
115
|
},
|
|
115
116
|
};
|