Skip to content

Commit b00c74d

Browse files
committed
Add artifact size table to compare page
1 parent a2e5ae7 commit b00c74d

File tree

5 files changed

+226
-1
lines changed

5 files changed

+226
-1
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<script setup lang="ts">
2+
import {ArtifactDescription} from "../types";
3+
import {diffClass, formatSize} from "../shared";
4+
5+
const props = defineProps<{
6+
a: ArtifactDescription;
7+
b: ArtifactDescription;
8+
}>();
9+
10+
// Sort binaries first, libraries later. Then within each category, sort in descending order by size
11+
// of the original (a) artifact component.
12+
const components = Object.entries(props.a.component_sizes)
13+
.sort((a, b) => {
14+
const aLib = a[0].startsWith("lib");
15+
const bLib = b[0].startsWith("lib");
16+
if (aLib && !bLib) {
17+
return 1;
18+
} else if (!aLib && bLib) {
19+
return -1;
20+
} else {
21+
return b[1] - a[1];
22+
}
23+
})
24+
.map((item) => item[0]);
25+
26+
function formatName(component: string): string {
27+
if (component.startsWith("lib")) {
28+
return `${component}.so`;
29+
}
30+
return component;
31+
}
32+
33+
function formatValue(value: number | undefined): string {
34+
if (value === undefined) {
35+
return "-";
36+
}
37+
return formatSize(value);
38+
}
39+
40+
function formatChange(a: number | undefined, b: number | undefined): string {
41+
if (a === undefined || b === undefined) {
42+
return "-";
43+
}
44+
const diff = b - a;
45+
const formatted = formatSize(Math.abs(diff));
46+
if (diff < 0) {
47+
return `-${formatted}`;
48+
}
49+
return formatted;
50+
}
51+
52+
function formatPercentChange(
53+
a: number | undefined,
54+
b: number | undefined
55+
): string {
56+
if (a === undefined || b === undefined) {
57+
return "-";
58+
}
59+
return `${(((b - a) / a) * 100).toFixed(3)}%`;
60+
}
61+
62+
function getClass(a: number | undefined, b: number | undefined): string {
63+
if (a === undefined || b === undefined || a == b) {
64+
return "-";
65+
}
66+
return diffClass(b - a);
67+
}
68+
</script>
69+
70+
<template>
71+
<div class="category-title">Artifact component sizes</div>
72+
<table>
73+
<thead>
74+
<tr>
75+
<th>Component</th>
76+
<th>Before</th>
77+
<th>After</th>
78+
<th>Change</th>
79+
<th>% Change</th>
80+
</tr>
81+
</thead>
82+
<tbody>
83+
<tr v-for="component in components">
84+
<td class="component">{{ formatName(component) }}</td>
85+
<td>
86+
<div class="aligned">
87+
{{ formatValue(a.component_sizes[component]) }}
88+
</div>
89+
</td>
90+
<td>
91+
<div class="aligned">
92+
{{ formatValue(b.component_sizes[component]) }}
93+
</div>
94+
</td>
95+
<td
96+
:class="
97+
getClass(a.component_sizes[component], b.component_sizes[component])
98+
"
99+
>
100+
<div class="aligned">
101+
{{
102+
formatChange(
103+
a.component_sizes[component],
104+
b.component_sizes[component]
105+
)
106+
}}
107+
</div>
108+
</td>
109+
<td
110+
:class="
111+
getClass(a.component_sizes[component], b.component_sizes[component])
112+
"
113+
>
114+
<div class="aligned">
115+
{{
116+
formatPercentChange(
117+
a.component_sizes[component],
118+
b.component_sizes[component]
119+
)
120+
}}
121+
</div>
122+
</td>
123+
</tr>
124+
</tbody>
125+
</table>
126+
</template>
127+
128+
<style scoped lang="scss">
129+
table {
130+
table-layout: fixed;
131+
width: 100%;
132+
margin-top: 10px;
133+
134+
td,
135+
th {
136+
text-align: center;
137+
padding: 0.3em;
138+
}
139+
140+
.component {
141+
word-break: break-word;
142+
}
143+
144+
.aligned {
145+
text-align: right;
146+
147+
@media (min-width: 600px) {
148+
width: 120px;
149+
}
150+
}
151+
}
152+
</style>

site/frontend/src/pages/compare/page.vue

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
computeRuntimeComparisonsWithNonRelevant,
2929
defaultRuntimeFilter,
3030
} from "./runtime/common";
31+
import ArtifactSizeTable from "./artifact-size/artifact-size-table.vue";
3132
3233
function loadSelectorFromUrl(urlParams: Dict<string>): CompareSelector {
3334
const start = urlParams["start"] ?? "";
@@ -46,6 +47,7 @@ function loadTabFromUrl(urlParams: Dict<string>): Tab | null {
4647
compile: Tab.CompileTime,
4748
runtime: Tab.Runtime,
4849
bootstrap: Tab.Bootstrap,
50+
["artifact-size"]: Tab.ArtifactSize,
4951
};
5052
return tabs[tab] ?? null;
5153
}
@@ -121,10 +123,19 @@ const activeTab = computed((): Tab => {
121123
if (tab.value === Tab.Runtime && !runtimeDataAvailable.value) {
122124
return Tab.CompileTime;
123125
}
126+
if (tab.value === Tab.ArtifactSize && !artifactSizeAvailable.value) {
127+
return Tab.CompileTime;
128+
}
124129
return tab.value;
125130
});
126131
127132
const runtimeDataAvailable = computed(() => runtimeSummary.value !== null);
133+
const artifactSizeAvailable = computed(
134+
() =>
135+
data.value != null &&
136+
(Object.keys(data.value.a.component_sizes).length > 0 ||
137+
Object.keys(data.value.b.component_sizes).length > 0)
138+
);
128139
129140
function changeTab(newTab: Tab) {
130141
tab.value = newTab;
@@ -171,6 +182,9 @@ loadCompareData(selector, loading);
171182
/>
172183
</template>
173184
<BootstrapTable v-if="activeTab === Tab.Bootstrap" :data="data" />
185+
<template v-if="artifactSizeAvailable && activeTab === Tab.ArtifactSize">
186+
<ArtifactSizeTable :a="data.a" :b="data.b" />
187+
</template>
174188
</div>
175189
</div>
176190
<br />

site/frontend/src/pages/compare/shared.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export function formatDate(dateString: string): string {
77
date.getUTCDate()
88
)} `;
99
}
10+
1011
export function signIfPositive(pct: number): string {
1112
if (pct >= 0) {
1213
return "+";
@@ -34,3 +35,18 @@ export function diffClass(diff: number): string {
3435
}
3536
return "negative";
3637
}
38+
39+
const KiB = 1024;
40+
const MiB = KiB * 1024;
41+
const GiB = MiB * 1024;
42+
43+
export function formatSize(size: number): string {
44+
if (size >= GiB) {
45+
return `${(size / GiB).toFixed(2)} GiB`;
46+
} else if (size >= MiB) {
47+
return `${(size / MiB).toFixed(2)} MiB`;
48+
} else if (size >= KiB) {
49+
return `${(size / KiB).toFixed(2)} KiB`;
50+
}
51+
return `${size} B`;
52+
}

site/frontend/src/pages/compare/tabs.vue

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="tsx">
22
import {computed, h, ref, Ref} from "vue";
33
import {CompareResponse, Tab} from "./types";
4-
import {diffClass, percentClass} from "./shared";
4+
import {diffClass, formatSize, percentClass} from "./shared";
55
import {SummaryGroup} from "./data";
66
import SummaryPercentValue from "./summary/percent-value.vue";
77
import SummaryRange from "./summary/range.vue";
@@ -63,12 +63,30 @@ function SummaryTable({summary}: {summary: SummaryGroup}) {
6363
return <div>No relevant results</div>;
6464
}
6565
66+
function formatArtifactSize(size: number): string {
67+
if (size === 0) {
68+
return "???";
69+
}
70+
return formatSize(size);
71+
}
72+
6673
const bootstrapA = props.data.a.bootstrap_total;
6774
const bootstrapB = props.data.b.bootstrap_total;
6875
const bootstrapValid = bootstrapA > 0.0 && bootstrapB > 0.0;
6976
7077
const runtimeAvailable = computed(() => props.runtimeSummary !== null);
7178
79+
const totalSizeA = Object.values(props.data.a.component_sizes).reduce(
80+
(a, b) => a + b,
81+
0
82+
);
83+
const totalSizeB = Object.values(props.data.b.component_sizes).reduce(
84+
(a, b) => a + b,
85+
0
86+
);
87+
const sizesAvailable = totalSizeA > 0 || totalSizeB > 0;
88+
const bothSizesAvailable = totalSizeA > 0 && totalSizeB > 0;
89+
7290
const activeTab: Ref<Tab> = ref(props.initialTab);
7391
</script>
7492

@@ -119,6 +137,30 @@ const activeTab: Ref<Tab> = ref(props.initialTab);
119137
</div>
120138
</div>
121139
</div>
140+
<div
141+
class="tab"
142+
title="Artifact size: sizes of individual components of the two artifacts."
143+
v-if="sizesAvailable"
144+
:class="{selected: activeTab === Tab.ArtifactSize}"
145+
@click="changeTab(Tab.ArtifactSize)"
146+
>
147+
<div class="title">Artifact size</div>
148+
<div class="summary">
149+
<div>
150+
{{ formatArtifactSize(totalSizeA) }} ->
151+
{{ formatArtifactSize(totalSizeB) }}
152+
</div>
153+
<div
154+
v-if="bothSizesAvailable"
155+
:class="diffClass(totalSizeB - totalSizeA)"
156+
>
157+
{{ totalSizeB < totalSizeA ? "-" : ""
158+
}}{{ formatSize(Math.abs(totalSizeB - totalSizeA)) }} ({{
159+
(((totalSizeB - totalSizeA) / totalSizeA) * 100).toFixed(3)
160+
}}%)
161+
</div>
162+
</div>
163+
</div>
122164
</div>
123165
</template>
124166

site/frontend/src/pages/compare/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ export enum Tab {
5252
CompileTime = "compile",
5353
Runtime = "runtime",
5454
Bootstrap = "bootstrap",
55+
ArtifactSize = "artifact-size",
5556
}

0 commit comments

Comments
 (0)