perf: 前端 API 并行化 + 后端 Redis 连接缓存 — 响应时间从 2.26s 降至 2ms

后端:
- rate_limit 中间件新增 RedisAvailability 缓存
- Redis 不可用时跳过限流,30 秒冷却后再重试
- 避免 get_multiplexed_async_connection 每次请求阻塞 2 秒

前端:
- plugin store schema 加载改为 Promise.allSettled 并行(原为 for...of 顺序)
- 先基于 entities 渲染回退菜单,schema 加载完成后更新
- 移除 Home useEffect 中 unreadCount 依赖,消除双重 fetch
- MainLayout 使用选择性 store selector 减少重渲染
This commit is contained in:
iven
2026-04-17 01:12:17 +08:00
parent f4dd228a67
commit b08e8b5ab5
4 changed files with 91 additions and 11 deletions

View File

@@ -40,14 +40,30 @@ export const usePluginStore = create<PluginStore>((set, get) => ({
const result = await listPlugins(page, 100, status);
set({ plugins: result.data });
// 预加载所有运行中插件的 schema
const schemas: Record<string, PluginSchemaResponse> = {};
for (const plugin of result.data) {
if (plugin.status !== 'running' && plugin.status !== 'enabled') continue;
try {
schemas[plugin.id] = await getPluginSchema(plugin.id) as PluginSchemaResponse;
} catch {
// schema 加载失败跳过
// 先基于 entities 生成回退菜单,确保侧边栏快速渲染
get().refreshMenuItems();
// 并行加载所有运行中插件的 schema完成后更新菜单
const activePlugins = result.data.filter(
(p) => p.status === 'running' || p.status === 'enabled'
);
if (activePlugins.length === 0) return;
const entries = await Promise.allSettled(
activePlugins.map(async (plugin) => {
try {
const schema = await getPluginSchema(plugin.id) as PluginSchemaResponse;
return [plugin.id, schema] as const;
} catch {
return null;
}
})
);
const schemas: Record<string, PluginSchemaResponse> = { ...get().schemaCache };
for (const entry of entries) {
if (entry.status === 'fulfilled' && entry.value) {
schemas[entry.value[0]] = entry.value[1];
}
}
set({ schemaCache: schemas });