From e688b2959cc661c95d7ae801b024289443adbdc0 Mon Sep 17 00:00:00 2001 From: Konv Suu <2583695112@qq.com> Date: Wed, 23 Jul 2025 00:48:13 +0800 Subject: [PATCH] fix: use lru-cache lib to improve alive minApp (#8187) * feat: use lru-cache lib to improve alive minApp * update * update * update * Remove unused dependency * update * update * update * update * fix warning * update --- src/renderer/src/hooks/useMinappPopup.ts | 58 +++++++++++++++++++----- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/src/renderer/src/hooks/useMinappPopup.ts b/src/renderer/src/hooks/useMinappPopup.ts index 010136ae2a..0ae339f6dc 100644 --- a/src/renderer/src/hooks/useMinappPopup.ts +++ b/src/renderer/src/hooks/useMinappPopup.ts @@ -9,8 +9,11 @@ import { setOpenedOneOffMinapp } from '@renderer/store/runtime' import { MinAppType } from '@renderer/types' +import { LRUCache } from 'lru-cache' import { useCallback } from 'react' +let minAppsCache: LRUCache + /** * Usage: * @@ -30,25 +33,53 @@ export const useMinappPopup = () => { const { openedKeepAliveMinapps, openedOneOffMinapp, minappShow } = useRuntime() const { maxKeepAliveMinapps } = useSettings() // 使用设置中的值 + const createLRUCache = useCallback(() => { + return new LRUCache({ + max: maxKeepAliveMinapps, + disposeAfter: () => { + dispatch(setOpenedKeepAliveMinapps(Array.from(minAppsCache.values()))) + }, + onInsert: () => { + dispatch(setOpenedKeepAliveMinapps(Array.from(minAppsCache.values()))) + }, + updateAgeOnGet: true, + updateAgeOnHas: true + }) + }, [dispatch, maxKeepAliveMinapps]) + + // 缓存不存在 + if (!minAppsCache) { + minAppsCache = createLRUCache() + } + + // 缓存数量大小发生了改变 + if (minAppsCache.max !== maxKeepAliveMinapps) { + // 1. 当前小程序数量小于等于设置的缓存数量,直接重新建立缓存 + if (minAppsCache.size <= maxKeepAliveMinapps) { + // LRU cache 机制,后 set 的会被放到前面,所以需要反转一下 + const oldEntries = Array.from(minAppsCache.entries()).reverse() + minAppsCache = createLRUCache() + oldEntries.forEach(([key, value]) => { + minAppsCache.set(key, value) + }) + } + // 2. 大于设置的缓存的话,就直到数量减少到设置的缓存数量 + } + /** Open a minapp (popup shows and minapp loaded) */ const openMinapp = useCallback( (app: MinAppType, keepAlive: boolean = false) => { if (keepAlive) { + // 通过 get 和 set 去更新缓存,避免重复添加 + const cacheApp = minAppsCache.get(app.id) + if (!cacheApp) minAppsCache.set(app.id, app) + // 如果小程序已经打开,只切换显示 if (openedKeepAliveMinapps.some((item) => item.id === app.id)) { dispatch(setCurrentMinappId(app.id)) dispatch(setMinappShow(true)) return } - - // 如果缓存数量未达上限,添加到缓存列表 - if (openedKeepAliveMinapps.length < maxKeepAliveMinapps) { - dispatch(setOpenedKeepAliveMinapps([app, ...openedKeepAliveMinapps])) - } else { - // 缓存数量达到上限,移除最后一个,添加新的 - dispatch(setOpenedKeepAliveMinapps([app, ...openedKeepAliveMinapps.slice(0, maxKeepAliveMinapps - 1)])) - } - dispatch(setOpenedOneOffMinapp(null)) dispatch(setCurrentMinappId(app.id)) dispatch(setMinappShow(true)) @@ -61,7 +92,7 @@ export const useMinappPopup = () => { dispatch(setMinappShow(true)) return }, - [dispatch, maxKeepAliveMinapps, openedKeepAliveMinapps] + [dispatch, openedKeepAliveMinapps] ) /** a wrapper of openMinapp(app, true) */ @@ -87,7 +118,7 @@ export const useMinappPopup = () => { const closeMinapp = useCallback( (appid: string) => { if (openedKeepAliveMinapps.some((item) => item.id === appid)) { - dispatch(setOpenedKeepAliveMinapps(openedKeepAliveMinapps.filter((item) => item.id !== appid))) + minAppsCache.delete(appid) } else if (openedOneOffMinapp?.id === appid) { dispatch(setOpenedOneOffMinapp(null)) } @@ -101,11 +132,14 @@ export const useMinappPopup = () => { /** Close all minapps (popup hides and all minapps unloaded) */ const closeAllMinapps = useCallback(() => { + // minAppsCache.clear 会多次调用 dispose 方法 + // 重新创建一个 LRU Cache 替换 + minAppsCache = createLRUCache() dispatch(setOpenedKeepAliveMinapps([])) dispatch(setOpenedOneOffMinapp(null)) dispatch(setCurrentMinappId('')) dispatch(setMinappShow(false)) - }, [dispatch]) + }, [dispatch, createLRUCache]) /** Hide the minapp popup (only one-off minapp unloaded) */ const hideMinappPopup = useCallback(() => {