fix: web search button memory leak (#9100)

* refactor(InputbarTools): 重命名getMenuItems为menuItems以提高可读性

* docs(Inputbar): 添加内存泄露风险注释

* Revert "refactor(InputbarTools): 重命名getMenuItems为menuItems以提高可读性"

This reverts commit 6076d5b74c.

* perf(WebSearchButton): 使用startTransition优化性能并移除setTimeout

移除setTimeout延迟更新,减少内存泄露,改用startTransition来优化UI卡顿问题,提升用户体验
This commit is contained in:
Phantom 2025-08-13 10:05:40 +08:00 committed by GitHub
parent e4e1325b08
commit 7c2a9d141e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,7 +7,7 @@ import { Assistant, WebSearchProvider } from '@renderer/types'
import { hasObjectKey } from '@renderer/utils' import { hasObjectKey } from '@renderer/utils'
import { Tooltip } from 'antd' import { Tooltip } from 'antd'
import { Globe } from 'lucide-react' import { Globe } from 'lucide-react'
import { FC, memo, useCallback, useImperativeHandle, useMemo } from 'react' import { FC, memo, startTransition, useCallback, useImperativeHandle, useMemo } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
export interface WebSearchButtonRef { export interface WebSearchButtonRef {
@ -29,23 +29,22 @@ const WebSearchButton: FC<Props> = ({ ref, assistant, ToolbarButton }) => {
const enableWebSearch = assistant?.webSearchProviderId || assistant.enableWebSearch const enableWebSearch = assistant?.webSearchProviderId || assistant.enableWebSearch
const updateSelectedWebSearchProvider = useCallback( const updateSelectedWebSearchProvider = useCallback(
(providerId?: WebSearchProvider['id']) => { async (providerId?: WebSearchProvider['id']) => {
// TODO: updateAssistant有性能问题会导致关闭快捷面板卡顿 // TODO: updateAssistant有性能问题会导致关闭快捷面板卡顿
// NOTE: 也许可以用startTransition优化卡顿问题 const currentWebSearchProviderId = assistant.webSearchProviderId
setTimeout(() => { const newWebSearchProviderId = currentWebSearchProviderId === providerId ? undefined : providerId
const currentWebSearchProviderId = assistant.webSearchProviderId startTransition(() => {
const newWebSearchProviderId = currentWebSearchProviderId === providerId ? undefined : providerId
updateAssistant({ ...assistant, webSearchProviderId: newWebSearchProviderId, enableWebSearch: false }) updateAssistant({ ...assistant, webSearchProviderId: newWebSearchProviderId, enableWebSearch: false })
}, 200) })
}, },
[assistant, updateAssistant] [assistant, updateAssistant]
) )
const updateSelectedWebSearchBuiltin = useCallback(() => { const updateSelectedWebSearchBuiltin = useCallback(async () => {
// TODO: updateAssistant有性能问题会导致关闭快捷面板卡顿 // TODO: updateAssistant有性能问题会导致关闭快捷面板卡顿
setTimeout(() => { startTransition(() => {
updateAssistant({ ...assistant, webSearchProviderId: undefined, enableWebSearch: !assistant.enableWebSearch }) updateAssistant({ ...assistant, webSearchProviderId: undefined, enableWebSearch: !assistant.enableWebSearch })
}, 200) })
}, [assistant, updateAssistant]) }, [assistant, updateAssistant])
const providerItems = useMemo<QuickPanelListItem[]>(() => { const providerItems = useMemo<QuickPanelListItem[]>(() => {
@ -92,11 +91,13 @@ const WebSearchButton: FC<Props> = ({ ref, assistant, ToolbarButton }) => {
const openQuickPanel = useCallback(() => { const openQuickPanel = useCallback(() => {
if (assistant.webSearchProviderId) { if (assistant.webSearchProviderId) {
return updateSelectedWebSearchProvider(undefined) updateSelectedWebSearchProvider(undefined)
return
} }
if (assistant.enableWebSearch) { if (assistant.enableWebSearch) {
return updateSelectedWebSearchBuiltin() updateSelectedWebSearchBuiltin()
return
} }
quickPanel.open({ quickPanel.open({