perf(web): debounce server and large-list searches (#6727)

This commit is contained in:
Seefs
2026-08-10 12:47:55 +08:00
committed by GitHub
parent 5d3423bec1
commit 7dd1000a19
10 changed files with 45 additions and 18 deletions
@@ -39,6 +39,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { useDebounce } from '@/hooks/use-debounce'
import type { UpstreamChannel } from '../types'
import {
@@ -80,6 +81,7 @@ export function ChannelSelectorDialog({
}: ChannelSelectorDialogProps) {
const { t } = useTranslation()
const [search, setSearch] = useState('')
const debouncedSearch = useDebounce(search, 200)
const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
useEffect(() => {
@@ -273,15 +275,15 @@ export function ChannelSelectorDialog({
)
const filteredChannels = useMemo(() => {
if (!search.trim()) return channels
if (!debouncedSearch.trim()) return channels
const searchLower = search.toLowerCase()
const searchLower = debouncedSearch.toLowerCase()
return channels.filter(
(ch) =>
ch.name.toLowerCase().includes(searchLower) ||
ch.base_url.toLowerCase().includes(searchLower)
)
}, [channels, search])
}, [channels, debouncedSearch])
const sortedChannels = useMemo(() => {
return [...filteredChannels].sort((a, b) => {
@@ -682,6 +682,7 @@ const ModelRatioVisualEditorComponent = forwardRef<
<DataTableToolbar
table={table}
searchPlaceholder={t('Search models...')}
searchDebounceMs={250}
filters={[
{
columnId: 'billingMode',
@@ -34,6 +34,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { useDebounce } from '@/hooks/use-debounce'
import type { DifferencesMap, RatioType } from '../types'
import { RATIO_TYPE_OPTIONS } from './constants'
@@ -88,6 +89,7 @@ export function UpstreamRatioSyncTable({
}: UpstreamRatioSyncTableProps) {
const { t } = useTranslation()
const [search, setSearch] = useState('')
const debouncedSearch = useDebounce(search, 250)
const [ratioTypeFilter, setRatioTypeFilter] = useState<string>('')
const dataSource = useMemo<ModelRow[]>(() => {
@@ -106,8 +108,8 @@ export function UpstreamRatioSyncTable({
const filteredData = useMemo(() => {
let data = dataSource
if (search.trim()) {
const lower = search.toLowerCase()
if (debouncedSearch.trim()) {
const lower = debouncedSearch.toLowerCase()
data = data.filter((row) => row.model.toLowerCase().includes(lower))
}
@@ -116,7 +118,7 @@ export function UpstreamRatioSyncTable({
}
return data
}, [dataSource, search, ratioTypeFilter])
}, [dataSource, debouncedSearch, ratioTypeFilter])
const upstreamNames = useMemo(() => {
const set = new Set<string>()