perf: optimize search

This commit is contained in:
skinmaker1345 2024-03-04 23:34:36 +09:00
parent 34a8ad2f24
commit ad90f8d699
2 changed files with 39 additions and 28 deletions

View File

@ -19,7 +19,7 @@ const Search: React.FC = () => {
const [recentSearch, setRecentSearch] = useState([])
const [data, setData] = useState<ResponseProps<ListAll>>(null)
const [loading, setLoading] = useState(false)
const [abortControl, setAbortControl] = useState(new AbortController())
const abortController = useRef(null)
const [hidden, setHidden] = useState(true)
useEffect(() => {
setQuery('')
@ -32,26 +32,37 @@ const Search: React.FC = () => {
}
}, [router])
useOutsideClick(ref, () => setHidden(true))
const SearchResults = async (value: string) => {
setData(null)
setQuery(value)
try {
abortControl.abort()
} catch (e) {
return null
useEffect(() => {
if (query.length < 2) {
setData(null)
return
}
const controller = new AbortController()
setAbortControl(controller)
if (value.length > 1) setLoading(true)
const res = await Fetch<ListAll>(`/search/all?q=${encodeURIComponent(value)}`, {
signal: controller.signal,
}).catch((e) => {
if (e.name !== 'AbortError') throw e
else return
})
setData(res || {})
setLoading(false)
}
const timeout = setTimeout(async () => {
setData(null)
try {
if (abortController.current) {
abortController.current.abort()
}
} catch (e) {
return null
}
abortController.current = new AbortController()
if (query.length > 1) setLoading(true)
const res = await Fetch<ListAll>(`/search/all?q=${encodeURIComponent(query)}`, {
signal: abortController.current.signal,
}).catch((e) => {
if (e.name !== 'AbortError') throw e
else return
})
abortController.current = null
setData(res || {})
setLoading(false)
}, 1000)
return () => {
clearTimeout(timeout)
}
}, [query])
const onSubmit = () => {
if (query.length < 2) return
@ -93,7 +104,7 @@ const Search: React.FC = () => {
placeholder='검색...'
value={query}
onChange={(e) => {
SearchResults(e.target.value)
setQuery(e.target.value)
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
@ -208,7 +219,7 @@ const Search: React.FC = () => {
))}
</>
)
) : query.length < 3 ? (
) : query.length < 2 ? (
'최소 2글자 이상 입력해주세요.'
) : (
'검색어를 입력해주세요.'

View File

@ -301,8 +301,8 @@ async function getBotList(type: ListType, page = 1, query?: string): Promise<Lis
)[0][0]['count(*)']
res = (
await knex.raw(
'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM bots WHERE `state` != "blocked" AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 16 OFFSET ?',
[decodeURI(query) + '*', decodeURI(query) + '*', ((page ? Number(page) : 1) - 1) * 16]
'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM bots WHERE `state` != "blocked" AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 8 OFFSET ?',
[decodeURI(query) + '*', decodeURI(query) + '*', ((page ? Number(page) : 1) - 1) * 8]
)
)[0]
} else {
@ -314,7 +314,7 @@ async function getBotList(type: ListType, page = 1, query?: string): Promise<Lis
type,
data: (await Promise.all(res.map(async (el) => await getBot(el.id)))).map((r) => ({ ...r })),
currentPage: page,
totalPage: Math.ceil(Number(count) / 16),
totalPage: Math.ceil(Number(count) / 8),
}
}
@ -402,12 +402,12 @@ async function getServerList(type: ListType, page = 1, query?: string): Promise<
)[0][0]['count(*)']
res = (
await knex.raw(
'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM servers WHERE `state` != "blocked" AND last_updated >= ? AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 16 OFFSET ?',
'SELECT id, votes, MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) as relevance FROM servers WHERE `state` != "blocked" AND last_updated >= ? AND MATCH(`name`, `intro`, `desc`) AGAINST(? in boolean mode) ORDER BY relevance DESC, votes DESC LIMIT 8 OFFSET ?',
[
decodeURI(query) + '*',
new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
decodeURI(query) + '*',
((page ? Number(page) : 1) - 1) * 16,
((page ? Number(page) : 1) - 1) * 8,
]
)
)[0]
@ -419,7 +419,7 @@ async function getServerList(type: ListType, page = 1, query?: string): Promise<
type,
data: (await Promise.all(res.map(async (el) => await getServer(el.id)))).map((r) => ({ ...r })),
currentPage: page,
totalPage: Math.ceil(Number(count) / 16),
totalPage: Math.ceil(Number(count) / 8),
}
}