mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 03:01:54 +00:00
[backport cloud/1.36] perf(AssetBrowserModal): virtualize asset grid to reduce network requests (#7922)
Backport of #7919 to `cloud/1.36` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7922-backport-cloud-1-36-perf-AssetBrowserModal-virtualize-asset-grid-to-reduce-network-re-2e36d73d3650812ca602d496f4decec4) by [Unito](https://www.unito.io) Co-authored-by: Alexander Brown <drjkl@comfy.org> Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -82,7 +82,7 @@
|
|||||||
{{ contentTitle }}
|
{{ contentTitle }}
|
||||||
</h2>
|
</h2>
|
||||||
<div
|
<div
|
||||||
class="min-h-0 px-6 pt-0 pb-10 overflow-y-auto scrollbar-custom"
|
class="min-h-0 flex-1 px-6 pt-0 pb-10 overflow-y-auto scrollbar-custom"
|
||||||
>
|
>
|
||||||
<slot name="content"></slot>
|
<slot name="content"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,28 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
data-component-id="AssetGrid"
|
data-component-id="AssetGrid"
|
||||||
:class="
|
class="h-full"
|
||||||
cn('grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-4 p-2')
|
|
||||||
"
|
|
||||||
role="grid"
|
role="grid"
|
||||||
:aria-label="$t('assetBrowser.assetCollection')"
|
:aria-label="$t('assetBrowser.assetCollection')"
|
||||||
:aria-rowcount="-1"
|
:aria-rowcount="-1"
|
||||||
:aria-colcount="-1"
|
:aria-colcount="-1"
|
||||||
:aria-setsize="assets.length"
|
:aria-setsize="assets.length"
|
||||||
>
|
>
|
||||||
<!-- Loading state -->
|
<div v-if="loading" class="flex h-full items-center justify-center py-20">
|
||||||
<div
|
|
||||||
v-if="loading"
|
|
||||||
class="col-span-full flex items-center justify-center py-20"
|
|
||||||
>
|
|
||||||
<i
|
<i
|
||||||
class="icon-[lucide--loader] size-12 animate-spin text-muted-foreground"
|
class="icon-[lucide--loader] size-12 animate-spin text-muted-foreground"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- Empty state -->
|
|
||||||
<div
|
<div
|
||||||
v-else-if="assets.length === 0"
|
v-else-if="assets.length === 0"
|
||||||
class="col-span-full flex flex-col items-center justify-center py-16 text-muted-foreground"
|
class="flex h-full flex-col items-center justify-center py-16 text-muted-foreground"
|
||||||
>
|
>
|
||||||
<i class="mb-4 icon-[lucide--search] size-10" />
|
<i class="mb-4 icon-[lucide--search] size-10" />
|
||||||
<h3 class="mb-2 text-lg font-medium">
|
<h3 class="mb-2 text-lg font-medium">
|
||||||
@@ -30,24 +23,33 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm">{{ $t('assetBrowser.tryAdjustingFilters') }}</p>
|
<p class="text-sm">{{ $t('assetBrowser.tryAdjustingFilters') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<VirtualGrid
|
||||||
<AssetCard
|
v-else
|
||||||
v-for="asset in assets"
|
:items="assetsWithKey"
|
||||||
:key="asset.id"
|
:grid-style="gridStyle"
|
||||||
:asset="asset"
|
:default-item-height="320"
|
||||||
:interactive="true"
|
:default-item-width="240"
|
||||||
@select="$emit('assetSelect', $event)"
|
>
|
||||||
/>
|
<template #item="{ item }">
|
||||||
</template>
|
<AssetCard
|
||||||
|
:asset="item"
|
||||||
|
:interactive="true"
|
||||||
|
@select="$emit('assetSelect', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VirtualGrid>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { CSSProperties } from 'vue'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
import VirtualGrid from '@/components/common/VirtualGrid.vue'
|
||||||
import AssetCard from '@/platform/assets/components/AssetCard.vue'
|
import AssetCard from '@/platform/assets/components/AssetCard.vue'
|
||||||
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
|
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
|
||||||
import { cn } from '@/utils/tailwindUtil'
|
|
||||||
|
|
||||||
defineProps<{
|
const { assets } = defineProps<{
|
||||||
assets: AssetDisplayItem[]
|
assets: AssetDisplayItem[]
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
}>()
|
}>()
|
||||||
@@ -55,4 +57,15 @@ defineProps<{
|
|||||||
defineEmits<{
|
defineEmits<{
|
||||||
assetSelect: [asset: AssetDisplayItem]
|
assetSelect: [asset: AssetDisplayItem]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const assetsWithKey = computed(() =>
|
||||||
|
assets.map((asset) => ({ ...asset, key: asset.id }))
|
||||||
|
)
|
||||||
|
|
||||||
|
const gridStyle: Partial<CSSProperties> = {
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fill, minmax(15rem, 1fr))',
|
||||||
|
gap: '1rem',
|
||||||
|
padding: '0.5rem'
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user