Skip to content

Commit ff2904b

Browse files
authored
performance: faster version table load in app for projects with a lot of game versions (#8089)
* performance: faster version table load by ensuring game versions is cached/reused in a vue computed * pnpm prepr
1 parent 11cdf9b commit ff2904b

2 files changed

Lines changed: 34 additions & 35 deletions

File tree

‎packages/ui/src/components/project/ProjectPageVersions.vue‎

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,7 @@
123123
<template #cell-gameVersions="{ row: version }">
124124
<div class="flex min-w-0 w-full max-w-[12rem] flex-wrap gap-1">
125125
<TagItem
126-
v-for="gameVersionGroup in getDisplayGameVersions(version).slice(
127-
0,
128-
MAX_GAME_VERSION_TAGS,
129-
)"
126+
v-for="gameVersionGroup in version.gameVersionGroups.slice(0, MAX_GAME_VERSION_TAGS)"
130127
:key="`version-tag-${gameVersionGroup.label}`"
131128
v-tooltip="getFilterTooltip(gameVersionGroup.label)"
132129
data-no-row-click
@@ -136,23 +133,21 @@
136133
<span class="min-w-0 truncate">{{ gameVersionGroup.label }}</span>
137134
</TagItem>
138135
<FloatingMenu
139-
v-if="getDisplayGameVersions(version).length > MAX_GAME_VERSION_TAGS"
136+
v-if="version.gameVersionGroups.length > MAX_GAME_VERSION_TAGS"
140137
trigger="hover"
141138
placement="bottom"
142139
data-no-row-click
143140
class="w-full min-w-0 cursor-default"
144141
>
145142
<TagItem class="w-fit max-w-full truncate" tabindex="0">
146143
<span class="min-w-0 truncate">
147-
+{{ getDisplayGameVersions(version).length - MAX_GAME_VERSION_TAGS }}
144+
+{{ version.gameVersionGroups.length - MAX_GAME_VERSION_TAGS }}
148145
</span>
149146
</TagItem>
150147
<template #popper>
151148
<div class="flex max-w-[20rem] flex-wrap gap-1">
152149
<TagItem
153-
v-for="gameVersionGroup in getDisplayGameVersions(version).slice(
154-
MAX_GAME_VERSION_TAGS,
155-
)"
150+
v-for="gameVersionGroup in version.gameVersionGroups.slice(MAX_GAME_VERSION_TAGS)"
156151
:key="`overflow-version-tag-${gameVersionGroup.label}`"
157152
class="w-fit max-w-full truncate"
158153
:action="
@@ -328,7 +323,7 @@
328323
<div class="flex flex-col justify-center gap-3">
329324
<div class="flex flex-row flex-wrap items-center gap-1.5">
330325
<TagItem
331-
v-for="gameVersionGroup in getDisplayGameVersions(version).slice(
326+
v-for="gameVersionGroup in version.gameVersionGroups.slice(
332327
0,
333328
MAX_GAME_VERSION_TAGS,
334329
)"
@@ -342,18 +337,18 @@
342337
{{ gameVersionGroup.label }}
343338
</TagItem>
344339
<FloatingMenu
345-
v-if="getDisplayGameVersions(version).length > MAX_GAME_VERSION_TAGS"
340+
v-if="version.gameVersionGroups.length > MAX_GAME_VERSION_TAGS"
346341
trigger="hover"
347342
placement="bottom"
348343
class="cursor-default smart-clickable:allow-pointer-events"
349344
>
350345
<TagItem tabindex="0">
351-
+{{ getDisplayGameVersions(version).length - MAX_GAME_VERSION_TAGS }}
346+
+{{ version.gameVersionGroups.length - MAX_GAME_VERSION_TAGS }}
352347
</TagItem>
353348
<template #popper>
354349
<div class="flex max-w-[20rem] flex-wrap gap-1">
355350
<TagItem
356-
v-for="gameVersionGroup in getDisplayGameVersions(version).slice(
351+
v-for="gameVersionGroup in version.gameVersionGroups.slice(
357352
MAX_GAME_VERSION_TAGS,
358353
)"
359354
:key="`overflow-version-tag-${gameVersionGroup.label}`"
@@ -526,7 +521,9 @@ type VersionTableColumn =
526521
| 'published'
527522
| 'downloads'
528523
| 'actions'
529-
type VersionTableRow = DisplayVersion & Record<string, unknown>
524+
type VersionTableRow = DisplayVersion & {
525+
gameVersionGroups: VersionDisplayGroup[]
526+
} & Record<string, unknown>
530527
531528
const props = withDefaults(
532529
defineProps<{
@@ -643,10 +640,6 @@ function hasNoModLoader(loaders: string[]): boolean {
643640
)
644641
}
645642
646-
function getDisplayGameVersions(version: DisplayVersion): VersionDisplayGroup[] {
647-
return getVersionGroupsForDisplay(version.game_versions, props.gameVersions)
648-
}
649-
650643
function getFilterTooltip(filter: string): string {
651644
return formatMessage(messages.toggleFilterTooltip, { filter })
652645
}
@@ -726,10 +719,12 @@ function isAnySelected(value: string, selected: string[]) {
726719
}
727720
728721
const currentVersions = computed(() =>
729-
filteredVersions.value.slice(
730-
(currentPage.value - 1) * pageSize.value,
731-
currentPage.value * pageSize.value,
732-
),
722+
filteredVersions.value
723+
.slice((currentPage.value - 1) * pageSize.value, currentPage.value * pageSize.value)
724+
.map((version) => ({
725+
...version,
726+
gameVersionGroups: getVersionGroupsForDisplay(version.game_versions, props.gameVersions),
727+
})),
733728
)
734729
const currentVersionRows = computed<VersionTableRow[]>(
735730
() => currentVersions.value as VersionTableRow[],

‎packages/utils/projects.ts‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export function getVersionGroupsForDisplay(
8888
): VersionDisplayGroup[] {
8989
const inputVersions = gameVersions.slice()
9090
const allVersions = allGameVersions.slice()
91+
const versionTags = new Map(allVersions.map((version) => [version.version, version]))
9192

9293
const allSnapshots = allVersions.filter((version) => version.version_type === 'snapshot')
9394
const allReleases = allVersions.filter((version) => version.version_type === 'release')
@@ -103,20 +104,20 @@ export function getVersionGroupsForDisplay(
103104
inputVersions.sort((a, b) => indices[a] - indices[b])
104105
}
105106

106-
const releaseVersions = inputVersions.filter((projVer) =>
107-
allReleases.some((gameVer) => gameVer.version === projVer),
107+
const releaseVersions = inputVersions.filter(
108+
(projVer) => versionTags.get(projVer)?.version_type === 'release',
108109
)
109110

110-
const dateString = allReleases.find((version) => version.version === releaseVersions[0])?.date
111+
const dateString = versionTags.get(releaseVersions[0])?.date
111112

112113
const latestReleaseVersionDate = dateString ? Date.parse(dateString) : 0
113-
const latestSnapshot = inputVersions.find((projVer) =>
114-
allSnapshots.some(
115-
(gameVer) =>
116-
gameVer.version === projVer &&
117-
(!latestReleaseVersionDate || latestReleaseVersionDate < Date.parse(gameVer.date)),
118-
),
119-
)
114+
const latestSnapshot = inputVersions.find((projVer) => {
115+
const gameVer = versionTags.get(projVer)
116+
return (
117+
gameVer?.version_type === 'snapshot' &&
118+
(!latestReleaseVersionDate || latestReleaseVersionDate < Date.parse(gameVer.date))
119+
)
120+
})
120121

121122
const allReleasesGrouped = groupVersions(
122123
allReleases.map((release) => release.version),
@@ -146,16 +147,19 @@ export function getVersionGroupsForDisplay(
146147
)
147148

148149
const legacyVersionsAsRanges = groupConsecutiveIndices(
149-
inputVersions.filter((projVer) => allLegacy.some((gameVer) => gameVer.version === projVer)),
150+
inputVersions.filter((projVer) => {
151+
const gameVer = versionTags.get(projVer)
152+
return gameVer && gameVer.version_type !== 'snapshot' && gameVer.version_type !== 'release'
153+
}),
150154
allLegacy,
151155
)
152156

153157
let output: VersionDisplayGroup[] = [...legacyVersionsAsRanges]
154158

155159
// show all snapshots if there's no release versions
156160
if (releaseVersionsAsRanges.length === 0) {
157-
const snapshotVersions = inputVersions.filter((projVer) =>
158-
allSnapshots.some((gameVer) => gameVer.version === projVer),
161+
const snapshotVersions = inputVersions.filter(
162+
(projVer) => versionTags.get(projVer)?.version_type === 'snapshot',
159163
)
160164
const snapshotVersionsAsRanges =
161165
snapshotVersions.length > 3

0 commit comments

Comments
 (0)