From 62e0d8e9dc9ddd294f5f564f645e03925a25f9bb Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 9 May 2026 17:28:23 +0800 Subject: [PATCH] perf: virtualize remaining long result views Reduce DOM growth across resource, history, workflow, share, downloading, and message views so large datasets stay responsive while scrolling. --- src/components/cards/TorrentCard.vue | 40 ++++-- src/components/cards/TorrentItem.vue | 53 ++++---- .../dialog/SubscribeHistoryDialog.vue | 114 +++++++++--------- src/pages/resource.vue | 76 ++++-------- src/utils/torrentDownloadCache.ts | 13 ++ src/views/reorganize/DownloadingListView.vue | 20 +-- src/views/subscribe/SubscribePopularView.vue | 26 ++-- src/views/subscribe/SubscribeShareView.vue | 18 ++- src/views/system/MessageView.vue | 29 ++--- src/views/workflow/WorkflowListView.vue | 16 ++- src/views/workflow/WorkflowShareView.vue | 20 ++- 11 files changed, 236 insertions(+), 189 deletions(-) create mode 100644 src/utils/torrentDownloadCache.ts diff --git a/src/components/cards/TorrentCard.vue b/src/components/cards/TorrentCard.vue index 239ba86c..e6b9b889 100644 --- a/src/components/cards/TorrentCard.vue +++ b/src/components/cards/TorrentCard.vue @@ -5,6 +5,8 @@ import api from '@/api' import type { Context } from '@/api/types' import AddDownloadDialog from '../dialog/AddDownloadDialog.vue' import { isNullOrEmptyObject } from '@/@core/utils' +import { getCachedSiteIcon } from '@/utils/siteIconCache' +import { downloadedTorrentMap, markTorrentDownloaded } from '@/utils/torrentDownloadCache' // 输入参数 const props = defineProps({ @@ -32,8 +34,7 @@ const downloadItem = ref(props.torrent) // 站点图标 const siteIcons = ref>({}) -// 存储是否已经下载过的记录 -const downloaded = ref([]) +const isDownloaded = computed(() => Boolean(torrent.value?.enclosure && downloadedTorrentMap[torrent.value.enclosure])) // 添加下载对话框 const addDownloadDialog = ref(false) @@ -41,8 +42,7 @@ const addDownloadDialog = ref(false) // 添加下载成功 function addDownloadSuccess(url: string) { addDownloadDialog.value = false - // 添加下载成功 - downloaded.value.push(url) + markTorrentDownloaded(url) } // 添加下载失败 @@ -53,10 +53,21 @@ function addDownloadError(error: string) { // 查询站点图标 async function getSiteIcon(site: number | undefined) { if (!site) return + try { - siteIcons.value[site] = (await api.get(`site/icon/${site}`)).data.icon + siteIcons.value[site] = await getCachedSiteIcon(site, async () => { + try { + const response = await api.get(`site/icon/${site}`) + + return response?.data?.icon || '' + } catch (error) { + console.error(error) + return '' + } + }) } catch (error) { console.error(error) + siteIcons.value[site] = '' } } @@ -109,20 +120,27 @@ async function openMoreTorrentsDialog() { showMoreTorrents.value = true } -// 装载时查询站点图标 -onMounted(() => { - getSiteIcon(props.torrent?.torrent_info?.site) -}) +watch( + () => props.torrent, + value => { + torrent.value = value?.torrent_info + media.value = value?.media_info + meta.value = value?.meta_info + downloadItem.value = value + getSiteIcon(value?.torrent_info?.site) + }, + { immediate: true }, +)