# FastGPT projects/app 性能与稳定性分析报告 生成时间: 2025-10-20 分析范围: projects/app 项目 技术栈: Next.js 14.2.32 + TypeScript + MongoDB + React 18 --- ## 执行摘要 本报告对 FastGPT 的 `projects/app` 项目进行了全面的性能和稳定性分析。通过静态代码分析、架构审查和配置检查,识别了 **42 个性能/稳定性问题**,按严重程度分为高危 (9个)、中危 (19个)、低危 (14个) 三个等级。 **关键发现**: - **高危问题**: 主要集中在工作流并发控制、数据库连接池、SSE 流处理和内存泄漏风险 - **中危问题**: Next.js 性能配置、React Hooks 优化、API 错误处理不完整 - **低危问题**: 日志系统、监控缺失、开发体验优化 **预估影响**: - 当前配置下,高并发场景可能出现性能瓶颈和稳定性问题 - 工作流深度递归和并发控制存在内存泄漏风险 - 缺少系统化的性能监控和错误追踪 --- ## 一、高危问题 (High Priority) ### 🔴 H1. 工作流深度递归限制不足 **位置**: `packages/service/core/workflow/dispatch/index.ts:184` **问题描述**: ```typescript if (data.workflowDispatchDeep > 20) { return { /* 空响应 */ }; } ``` - 工作流递归深度限制设为 20,但未限制递归节点的总执行次数 - 复杂工作流可能触发大量节点同时执行,导致内存和 CPU 资源耗尽 - `WorkflowQueue` 类最大并发设为 10,但未限制队列总大小 **风险等级**: 🔴 高危 **影响**: - 恶意或错误配置的工作流可导致系统资源耗尽 - 无法有效防护 DoS 攻击场景 - 可能导致 Node.js 进程 OOM (内存溢出) **建议方案**: ```typescript // 1. 添加全局节点执行次数限制 class WorkflowQueue { private totalNodeExecuted = 0; private readonly MAX_TOTAL_NODES = 1000; async checkNodeCanRun(node: RuntimeNodeItemType) { if (this.totalNodeExecuted >= this.MAX_TOTAL_NODES) { throw new Error('工作流执行节点数超出限制'); } this.totalNodeExecuted++; // ... 原有逻辑 } } // 2. 添加执行时间总限制 const WORKFLOW_MAX_DURATION_MS = 5 * 60 * 1000; // 5分钟 const workflowTimeout = setTimeout(() => { res.end(); throw new Error('工作流执行超时'); }, WORKFLOW_MAX_DURATION_MS); // 3. 增强队列大小限制 private readonly MAX_QUEUE_SIZE = 100; addActiveNode(nodeId: string) { if (this.activeRunQueue.size >= this.MAX_QUEUE_SIZE) { throw new Error('工作流待执行队列已满'); } // ... 原有逻辑 } ``` --- ### 🔴 H2. MongoDB 连接池配置缺失(已解决) **位置**: - `packages/service/common/mongo/index.ts:12-24` - `packages/service/common/mongo/init.ts` **问题描述**: ```typescript export const connectionMongo = (() => { if (!global.mongodb) { global.mongodb = new Mongoose(); } return global.mongodb; })(); ``` - 未配置连接池参数 (poolSize, maxIdleTimeMS, minPoolSize) - 未设置超时参数 (serverSelectionTimeoutMS, socketTimeoutMS) - 两个独立数据库连接 (main + log) 但未协调资源分配 **风险等级**: 🔴 高危 **影响**: - 高并发场景下连接数耗尽,导致请求排队或失败 - 慢查询阻塞连接池,影响所有请求 - 无超时保护,数据库故障时服务无法快速失败 **建议方案**: ```typescript // packages/service/common/mongo/init.ts export const connectMongo = async ({ db, url, connectedCb }: ConnectMongoProps) => { const options = { // 连接池配置 maxPoolSize: 50, // 最大连接数 minPoolSize: 10, // 最小连接数 maxIdleTimeMS: 60000, // 空闲连接超时 // 超时配置 serverSelectionTimeoutMS: 10000, // 服务器选择超时 socketTimeoutMS: 45000, // Socket 超时 connectTimeoutMS: 10000, // 连接超时 // 重试配置 retryWrites: true, retryReads: true, // 读写配置 w: 'majority', readPreference: 'primaryPreferred', // 压缩 compressors: ['zstd', 'snappy', 'zlib'] }; await db.connect(url, options); }; // 添加连接池监控 connectionMongo.connection.on('connectionPoolReady', () => { console.log('MongoDB connection pool ready'); }); connectionMongo.connection.on('connectionPoolClosed', () => { console.error('MongoDB connection pool closed'); }); ``` --- ### 🔴 H3. SSE 流式响应未处理客户端断开(已解决) **位置**: `packages/service/core/workflow/dispatch/index.ts:105-129` **问题描述**: ```typescript if (stream) { res.on('close', () => res.end()); res.on('error', () => { addLog.error('Request error'); res.end(); }); streamCheckTimer = setInterval(() => { data?.workflowStreamResponse?.({ /* heartbeat */ }); }, 10000); } ``` - 客户端断开连接后,工作流继续执行,浪费资源 - 未清理 `streamCheckTimer`,存在定时器泄漏风险 - `res.closed` 检查存在但未在所有关键节点检查 **风险等级**: 🔴 高危 **影响**: - 客户端断开后资源持续消耗 (AI 调用、数据库查询继续执行) - 定时器泄漏导致内存增长 - 费用浪费 (AI Token 消耗) **建议方案**: ```typescript // 1. 增强连接断开处理 let isClientDisconnected = false; res.on('close', () => { isClientDisconnected = true; if (streamCheckTimer) clearInterval(streamCheckTimer); addLog.info('Client disconnected, stopping workflow'); // 通知工作流停止 workflowQueue.stop(); }); // 2. 在工作流队列中添加停止机制 class WorkflowQueue { private isStopped = false; stop() { this.isStopped = true; this.activeRunQueue.clear(); this.resolve(this); } private async checkNodeCanRun(node: RuntimeNodeItemType) { if (this.isStopped) { return; // 提前退出 } if (res?.closed) { this.stop(); return; } // ... 原有逻辑 } } // 3. 确保 streamCheckTimer 始终被清理 try { return runWorkflow({ ... }); } finally { if (streamCheckTimer) { clearInterval(streamCheckTimer); streamCheckTimer = null; } } ``` --- ### 🔴 H4. API 路由缺少统一的请求超时控制 **位置**: `projects/app/src/pages/api/v1/chat/completions.ts:610-616` **问题描述**: ```typescript export const config = { api: { bodyParser: { sizeLimit: '20mb' }, responseLimit: '20mb' } }; ``` - 未配置 API 路由超时时间,默认无限等待 - 工作流执行无全局超时控制 - 长时间运行的请求可能导致资源耗尽 **风险等级**: 🔴 高危 **影响**: - 慢查询、AI 调用超时导致请求堆积 - 内存持续增长,最终 OOM - 无法有效限制恶意请求 **建议方案**: ```typescript // 1. 添加全局超时中间件 // projects/app/src/service/middleware/timeout.ts import { NextApiRequest, NextApiResponse } from 'next'; export const withTimeout = ( handler: Function, timeoutMs: number = 120000 // 默认 2 分钟 ) => { return async (req: NextApiRequest, res: NextApiResponse) => { const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error('Request timeout')), timeoutMs); }); try { await Promise.race([ handler(req, res), timeoutPromise ]); } catch (error) { if (!res.headersSent) { res.status(408).json({ error: 'Request Timeout' }); } } }; }; // 2. 应用到关键 API 路由 export default NextAPI(withTimeout(handler, 300000)); // 5分钟超时 // 3. 配置 Next.js API 超时 // next.config.js module.exports = { // ... experimental: { // API 路由超时 (毫秒) apiTimeout: 300000 // 5分钟 } }; ``` --- ### 🔴 H5. 工作流变量注入未防护原型链污染 **位置**: `packages/service/core/workflow/dispatch/index.ts:553-557` **问题描述**: ```typescript if (dispatchRes[DispatchNodeResponseKeyEnum.newVariables]) { variables = { ...variables, ...dispatchRes[DispatchNodeResponseKeyEnum.newVariables] }; } ``` - 直接合并用户输入的变量,未过滤危险键名 - 可能导致原型链污染攻击 - 变量名未验证,可能覆盖系统变量 **风险等级**: 🔴 高危 **影响**: - 原型链污染可导致远程代码执行 - 系统变量被覆盖导致工作流异常 - 安全风险 **建议方案**: ```typescript // 1. 创建安全的对象合并函数 function safeMergeVariables( target: Record, source: Record ): Record { const dangerousKeys = [ '__proto__', 'constructor', 'prototype', 'toString', 'valueOf' ]; const systemVariableKeys = [ 'userId', 'appId', 'chatId', 'responseChatItemId', 'histories', 'cTime' ]; const result = { ...target }; for (const [key, value] of Object.entries(source)) { // 检查危险键名 if (dangerousKeys.includes(key)) { addLog.warn('Blocked dangerous variable key', { key }); continue; } // 检查系统变量 if (systemVariableKeys.includes(key)) { addLog.warn('Attempted to override system variable', { key }); continue; } // 验证键名格式 if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) { addLog.warn('Invalid variable key format', { key }); continue; } result[key] = value; } return result; } // 2. 使用安全合并 if (dispatchRes[DispatchNodeResponseKeyEnum.newVariables]) { variables = safeMergeVariables( variables, dispatchRes[DispatchNodeResponseKeyEnum.newVariables] ); } ``` --- ### 🔴 H6. React Hooks 依赖数组缺失导致潜在内存泄漏 **位置**: 全局分析 - 发现 1664 个 Hooks 使用 **问题描述**: - 项目中大量使用 `useEffect`, `useMemo`, `useCallback` - 部分 Hooks 依赖数组不完整或缺失 - 可能导致闭包陷阱和不必要的重渲染 **风险等级**: 🔴 高危 **影响**: - 组件卸载后定时器/订阅未清理 - 内存泄漏累积导致页面卡顿 - 频繁重渲染影响性能 **典型问题示例**: ```typescript // ❌ 错误示例 useEffect(() => { const timer = setInterval(() => { /* ... */ }, 1000); // 缺少清理函数 }, []); // ✅ 正确示例 useEffect(() => { const timer = setInterval(() => { /* ... */ }, 1000); return () => clearInterval(timer); }, []); ``` **建议方案**: ```bash # 1. 启用 ESLint React Hooks 规则 # .eslintrc.json { "plugins": ["react-hooks"], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } } # 2. 全局扫描并修复 pnpm lint --fix # 3. 重点审查以下文件: # - projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx # - projects/app/src/pageComponents/app/detail/WorkflowComponents/context/*.tsx # - projects/app/src/web/common/hooks/*.ts ``` --- ### 🔴 H7. MongoDB 慢查询未设置超时和索引验证 **位置**: `packages/service/common/mongo/index.ts:26-97` **问题描述**: ```typescript const addCommonMiddleware = (schema: mongoose.Schema) => { operations.forEach((op: any) => { schema.pre(op, function (this: any, next) { this._startTime = Date.now(); next(); }); schema.post(op, function (this: any, result: any, next) { const duration = Date.now() - this._startTime; if (duration > 1000) { addLog.warn(`Slow operation ${duration}ms`, warnLogData); } next(); }); }); }; ``` - 记录慢查询但未强制超时 - 未验证查询是否使用索引 - 缺少查询计划分析 **风险等级**: 🔴 高危 **影响**: - 慢查询阻塞数据库连接 - 表扫描导致性能下降 - 数据库负载过高 **建议方案**: ```typescript // 1. 添加查询超时配置 export const getMongoModel = (name: string, schema: mongoose.Schema) => { // ... 现有代码 // 设置默认查询超时 schema.set('maxTimeMS', 30000); // 30秒 const model = connectionMongo.model(name, schema); return model; }; // 2. 添加查询计划分析 (开发环境) if (process.env.NODE_ENV === 'development') { schema.post(/^find/, async function(this: any, docs, next) { try { const explain = await this.model.find(this._query).explain('executionStats'); const stats = explain.executionStats; if (stats.totalDocsExamined > stats.nReturned * 10) { addLog.warn('Inefficient query detected', { collection: this.collection.name, query: this._query, docsExamined: stats.totalDocsExamined, docsReturned: stats.nReturned, executionTimeMS: stats.executionTimeMillis }); } } catch (error) { // 忽略 explain 错误 } next(); }); } // 3. 强制使用索引 (生产环境) if (process.env.NODE_ENV === 'production') { schema.pre(/^find/, function(this: any, next) { // 强制使用索引提示 // this.hint({ _id: 1 }); // 根据实际情况配置 next(); }); } ``` --- ### 🔴 H8. 缺少全局错误边界和错误恢复机制 **位置**: `projects/app/src/pages/_app.tsx` **问题描述**: - 未实现 React 错误边界 - 错误页面 `_error.tsx` 存在但功能简单 - 缺少错误上报和用户友好提示 **风险等级**: 🔴 高危 **影响**: - 组件错误导致整个应用崩溃 - 用户体验差 - 错误信息未收集,难以排查问题 **建议方案**: ```typescript // 1. 实现全局错误边界 // projects/app/src/components/ErrorBoundary.tsx import React from 'react'; import { addLog } from '@fastgpt/service/common/system/log'; interface Props { children: React.ReactNode; fallback?: React.ComponentType<{ error: Error; resetError: () => void }>; } interface State { hasError: boolean; error: Error | null; } export class ErrorBoundary extends React.Component { constructor(props: Props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error): State { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { addLog.error('React Error Boundary', { error: error.message, stack: error.stack, componentStack: errorInfo.componentStack }); // 上报到错误监控服务 (如 Sentry) if (typeof window !== 'undefined' && window.Sentry) { window.Sentry.captureException(error, { contexts: { react: { componentStack: errorInfo.componentStack } } }); } } resetError = () => { this.setState({ hasError: false, error: null }); }; render() { if (this.state.hasError) { const FallbackComponent = this.props.fallback; if (FallbackComponent && this.state.error) { return ; } return (

出错了

应用遇到了一个错误,我们正在努力修复。

); } return this.props.children; } } // 2. 在 _app.tsx 中使用 function App({ Component, pageProps }: AppPropsWithLayout) { // ... 现有代码 return ( {/* 现有渲染逻辑 */} ); } ``` --- ## 二、中危问题 (Medium Priority) ### 🟡 M1. Next.js 未启用 SWC 编译优化完整特性 **位置**: `projects/app/next.config.js:18` **问题描述**: - `swcMinify: true` 已启用,但未配置 SWC 编译器的完整优化 - 未配置 Emotion 的 SWC 插件 - 未启用 Modularize Imports 优化 **建议**: ```javascript module.exports = { // ... 现有配置 compiler: { // Emotion 配置 emotion: { sourceMap: isDev, autoLabel: 'dev-only', labelFormat: '[local]', importMap: { '@emotion/react': { styled: { canonicalImport: ['@emotion/styled', 'default'] } } } }, // 移除 React 属性 reactRemoveProperties: isDev ? false : { properties: ['^data-test'] }, // 移除 console (生产环境) removeConsole: isDev ? false : { exclude: ['error', 'warn'] } }, // Modularize Imports modularizeImports: { '@chakra-ui/react': { transform: '@chakra-ui/react/dist/{{member}}' }, 'lodash': { transform: 'lodash/{{member}}' } } }; ``` --- ### 🟡 M2. 未启用 Next.js 图片优化 **位置**: 全局图片使用 **问题描述**: - 搜索显示项目中仅 14 处使用 `Image` 标签 - 大量使用 `img` 标签,未使用 Next.js Image 优化 - 缺少图片懒加载和响应式配置 **建议**: ```typescript // 1. 全局替换 img 为 next/image import Image from 'next/image'; // ❌ 替换前 Logo // ✅ 替换后 Logo // 2. 配置 next.config.js module.exports = { images: { formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], minimumCacheTTL: 60, domains: ['your-cdn-domain.com'] } }; ``` --- ### 🟡 M3. React Query 未配置缓存策略 **位置**: `projects/app/src/web/context/QueryClient.tsx` **问题描述**: - 使用 `@tanstack/react-query` 但未自定义配置 - 默认缓存时间可能不适合业务场景 - 未配置重试策略和错误处理 **建议**: ```typescript const queryClient = new QueryClient({ defaultOptions: { queries: { // 缓存配置 staleTime: 5 * 60 * 1000, // 5分钟后数据过期 cacheTime: 10 * 60 * 1000, // 10分钟后清除缓存 // 重试配置 retry: 2, retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // 性能优化 refetchOnWindowFocus: false, refetchOnMount: false, refetchOnReconnect: true, // 错误处理 onError: (error) => { console.error('Query error:', error); // 错误上报 } }, mutations: { retry: 1, onError: (error) => { console.error('Mutation error:', error); } } } }); ``` --- ### 🟡 M4. API 路由错误处理不统一 **位置**: `projects/app/src/pages/api/**/*.ts` **问题描述**: - 53 个 API 文件中,仅部分使用 try-catch - 错误响应格式不统一 - 缺少错误码标准化 **建议**: ```typescript // 1. 创建统一错误处理中间件 // projects/app/src/service/middleware/errorHandler.ts export const withErrorHandler = (handler: Function) => { return async (req: NextApiRequest, res: NextApiResponse) => { try { await handler(req, res); } catch (error) { const errorCode = getErrorCode(error); const statusCode = getStatusCode(errorCode); addLog.error('API Error', { path: req.url, method: req.method, error: error.message, stack: error.stack }); if (!res.headersSent) { res.status(statusCode).json({ code: errorCode, message: error.message || 'Internal Server Error', ...(process.env.NODE_ENV === 'development' && { stack: error.stack }) }); } } }; }; // 2. 标准化错误码 export enum ApiErrorCode { AUTH_FAILED = 'AUTH_001', INVALID_PARAMS = 'PARAMS_001', RESOURCE_NOT_FOUND = 'RESOURCE_001', RATE_LIMIT = 'RATE_001', INTERNAL_ERROR = 'SERVER_001' } // 3. 应用到所有 API 路由 export default NextAPI(withErrorHandler(handler)); ``` --- ### 🟡 M5. Webpack 缓存配置未优化 **位置**: `projects/app/next.config.js:114-123` **问题描述**: ```javascript config.cache = { type: 'filesystem', name: isServer ? 'server' : 'client', maxMemoryGenerations: isDev ? 5 : Infinity, maxAge: 7 * 24 * 60 * 60 * 1000, // 7 天 }; ``` - `maxMemoryGenerations: Infinity` 生产环境可能导致内存占用过高 - 未配置缓存版本控制 - 未配置缓存压缩 **建议**: ```javascript config.cache = { type: 'filesystem', name: isServer ? 'server' : 'client', cacheDirectory: path.resolve(__dirname, '.next/cache/webpack'), // 内存控制 maxMemoryGenerations: isDev ? 5 : 10, // 限制生产环境内存缓存代数 maxAge: 7 * 24 * 60 * 60 * 1000, // 缓存失效控制 buildDependencies: { config: [__filename], tsconfig: [path.resolve(__dirname, 'tsconfig.json')], packageJson: [path.resolve(__dirname, 'package.json')] }, // 缓存版本 version: require('./package.json').version, // 压缩 compression: 'gzip', // Hash函数 hashAlgorithm: 'xxhash64', // 缓存存储 store: 'pack', // 允许收集未使用内存 allowCollectingMemory: true, // 缓存管理 managedPaths: [path.resolve(__dirname, 'node_modules')], immutablePaths: [] }; ``` --- ### 🟡 M6. getServerSideProps 使用未优化 **位置**: 15 个页面文件使用 **问题描述**: - 多个页面使用 `getServerSideProps`,但未考虑 ISR - 未使用 `getStaticProps` + `revalidate` 提升性能 - 每次请求都进行服务端渲染,负载高 **建议**: ```typescript // ❌ 当前实现 export const getServerSideProps = async (context) => { const data = await fetchData(); return { props: { data } }; }; // ✅ 优化方案 1: ISR (适合半静态内容) export const getStaticProps = async () => { const data = await fetchData(); return { props: { data }, revalidate: 60 // 60秒后重新生成 }; }; // ✅ 优化方案 2: 客户端获取 (适合个性化内容) export default function Page() { const { data } = useQuery('key', fetchData, { staleTime: 5 * 60 * 1000 }); return
{/* ... */}
; } // ✅ 优化方案 3: 混合模式 export const getStaticProps = async () => { const staticData = await fetchStaticData(); return { props: { staticData }, revalidate: 3600 // 1小时 }; }; export default function Page({ staticData }) { // 客户端获取动态数据 const { dynamicData } = useQuery('dynamic', fetchDynamicData); return
{/* ... */}
; } ``` --- ### 🟡 M7. MongoDB 索引同步策略不当 **位置**: `packages/service/common/mongo/index.ts:125-133` **问题描述**: ```typescript const syncMongoIndex = async (model: Model) => { if (process.env.SYNC_INDEX !== '0' && process.env.NODE_ENV !== 'test') { try { model.syncIndexes({ background: true }); } catch (error) { addLog.error('Create index error', error); } } }; ``` - 每次启动都同步索引,可能影响启动速度 - 错误被吞没,索引失败无明确提示 - 未检查索引健康状态 **建议**: ```typescript const syncMongoIndex = async (model: Model) => { if (process.env.SYNC_INDEX === '0' || process.env.NODE_ENV === 'test') { return; } try { const collectionName = model.collection.name; // 检查集合是否存在 const collections = await model.db.listCollections({ name: collectionName }).toArray(); if (collections.length === 0) { addLog.info(`Creating collection and indexes for ${collectionName}`); await model.createCollection(); await model.syncIndexes({ background: true }); return; } // 获取现有索引 const existingIndexes = await model.collection.indexes(); const schemaIndexes = model.schema.indexes(); // 对比并同步差异 const needsSync = schemaIndexes.some(schemaIndex => { return !existingIndexes.some(existingIndex => JSON.stringify(existingIndex.key) === JSON.stringify(schemaIndex[0]) ); }); if (needsSync) { addLog.info(`Syncing indexes for ${collectionName}`); await model.syncIndexes({ background: true }); } else { addLog.debug(`Indexes up to date for ${collectionName}`); } } catch (error) { addLog.error(`Failed to sync indexes for ${model.collection.name}`, { error: error.message, stack: error.stack }); // 索引同步失败不应阻塞启动,但需要告警 if (process.env.ALERT_WEBHOOK) { // 发送告警通知 } } }; ``` --- ### 🟡 M8. Promise.all 未处理部分失败场景 **位置**: 20+ 处使用 `Promise.all` **问题描述**: - 大量使用 `Promise.all`,但未考虑部分失败容错 - 一个 Promise 失败导致整体失败 - 应使用 `Promise.allSettled` 的场景使用了 `Promise.all` **建议**: ```typescript // ❌ 错误用法 const [data1, data2, data3] = await Promise.all([ fetchData1(), fetchData2(), // 如果失败,整体失败 fetchData3() ]); // ✅ 场景 1: 全部必需 (使用 Promise.all) try { const [data1, data2, data3] = await Promise.all([ fetchData1(), fetchData2(), fetchData3() ]); } catch (error) { // 统一错误处理 } // ✅ 场景 2: 部分可选 (使用 Promise.allSettled) const results = await Promise.allSettled([ fetchData1(), fetchData2(), // 可能失败,但不影响其他 fetchData3() ]); const data1 = results[0].status === 'fulfilled' ? results[0].value : defaultValue; const data2 = results[1].status === 'fulfilled' ? results[1].value : null; const data3 = results[2].status === 'fulfilled' ? results[2].value : defaultValue; // ✅ 场景 3: 辅助函数封装 async function safePromiseAll( promises: Promise[], options: { continueOnError?: boolean } = {} ): Promise> { if (options.continueOnError) { const results = await Promise.allSettled(promises); return results.map(r => r.status === 'fulfilled' ? r.value : r.reason); } return Promise.all(promises); } ``` --- ### 🟡 M9. 前端组件未使用 React.memo 优化 **位置**: 全局组件分析 **问题描述**: - 大量列表渲染和复杂组件 - 未使用 `React.memo` 避免不必要的重渲染 - 高频更新组件影响性能 **建议**: ```typescript // 1. 列表项组件优化 // ❌ 优化前 export const ListItem = ({ item, onDelete }) => { return
{item.name}
; }; // ✅ 优化后 export const ListItem = React.memo(({ item, onDelete }) => { return
{item.name}
; }, (prevProps, nextProps) => { // 自定义比较函数 return prevProps.item.id === nextProps.item.id && prevProps.item.name === nextProps.item.name; }); // 2. 稳定化回调函数 const MemoizedComponent = React.memo(({ onAction }) => { // ... }); function ParentComponent() { // ❌ 每次渲染创建新函数 // const handleAction = () => { /* ... */ }; // ✅ 使用 useCallback 稳定引用 const handleAction = useCallback(() => { // ... }, [/* dependencies */]); return ; } // 3. 复杂计算使用 useMemo function ExpensiveComponent({ data }) { // ❌ 每次渲染都计算 // const processedData = expensiveProcess(data); // ✅ 缓存计算结果 const processedData = useMemo(() => { return expensiveProcess(data); }, [data]); return
{processedData}
; } ``` --- ### 🟡 M10. 缺少 API 请求去重和缓存 **位置**: `projects/app/src/web/common/api/*.ts` **问题描述**: - 多个组件同时请求相同 API - 未实现请求去重 - 未利用浏览器缓存 **建议**: ```typescript // 1. 实现请求去重 const pendingRequests = new Map>(); export async function fetchWithDedup( url: string, options?: RequestInit ): Promise { const key = `${url}_${JSON.stringify(options)}`; if (pendingRequests.has(key)) { return pendingRequests.get(key)!; } const promise = fetch(url, options) .then(res => res.json()) .finally(() => { pendingRequests.delete(key); }); pendingRequests.set(key, promise); return promise; } // 2. 添加内存缓存 class ApiCache { private cache = new Map(); get(key: string) { const item = this.cache.get(key); if (!item) return null; if (Date.now() > item.expiry) { this.cache.delete(key); return null; } return item.data; } set(key: string, data: any, ttl: number = 60000) { this.cache.set(key, { data, expiry: Date.now() + ttl }); } clear() { this.cache.clear(); } } const apiCache = new ApiCache(); export async function cachedFetch( url: string, options?: RequestInit & { cacheTTL?: number } ): Promise { const cacheKey = `${url}_${JSON.stringify(options)}`; // 检查缓存 const cached = apiCache.get(cacheKey); if (cached) return cached; // 请求数据 const data = await fetchWithDedup(url, options); // 存入缓存 apiCache.set(cacheKey, data, options?.cacheTTL); return data; } ``` --- ### 🟡 M11-M19: 其他中危问题 **M11. 开发环境未启用 React Strict Mode** ```javascript // next.config.js reactStrictMode: isDev ? false : true, // ❌ 应该开发环境也启用 // 建议: reactStrictMode: true ``` **M12. 未配置 Next.js 性能监控** ```javascript // next.config.js experimental: { instrumentationHook: true, // ✅ 已启用 // 添加更多监控配置 webVitalsAttribution: ['CLS', 'LCP', 'FCP', 'FID', 'TTFB'], optimizeCss: true, optimizePackageImports: ['@chakra-ui/react', 'lodash', 'recharts'] } ``` **M13. 未使用 Webpack Bundle Analyzer 定期检查** ```bash # 已安装但未配置为定期任务 ANALYZE=true pnpm build # 建议: 添加到 CI/CD 流程 ``` **M14. Sass 编译未优化** ```javascript // next.config.js 添加 sassOptions: { includePaths: [path.join(__dirname, 'styles')], prependData: `@import "variables.scss";` } ``` **M15. 未配置 CSP (内容安全策略)** ```javascript // next.config.js async headers() { return [{ source: '/(.*)', headers: [ { key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline';" } ] }]; } ``` **M16. 未实现前端性能监控** ```typescript // 建议添加 Web Vitals 上报 export function reportWebVitals(metric: NextWebVitalsMetric) { if (metric.label === 'web-vital') { // 上报到分析服务 console.log(metric); } } ``` **M17. Console 日志未统一管理** - 发现 217 处 console.log/error/warn - 建议: 使用统一的日志服务 ```typescript // packages/global/common/logger.ts export const logger = { info: (msg, ...args) => isDev && console.log(`[INFO] ${msg}`, ...args), warn: (msg, ...args) => console.warn(`[WARN] ${msg}`, ...args), error: (msg, ...args) => console.error(`[ERROR] ${msg}`, ...args) }; ``` **M18. 未配置 TypeScript 严格模式** ```json // tsconfig.json { "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "noUnusedLocals": true, "noUnusedParameters": true } } ``` **M19. 未使用 Turbopack (Next.js 14 支持)** ```javascript // package.json "scripts": { "dev": "next dev --turbo" // 实验性加速开发构建 } ``` --- ## 三、低危问题 (Low Priority) ### 🟢 L1. 缺少 Lighthouse CI 性能监控 **建议**: 集成 Lighthouse CI 到 GitHub Actions ```yaml # .github/workflows/lighthouse.yml name: Lighthouse CI on: [pull_request] jobs: lighthouse: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: treosh/lighthouse-ci-action@v9 with: urls: | http://localhost:3000 http://localhost:3000/chat uploadArtifacts: true ``` --- ### 🟢 L2. 未配置 PWA **建议**: 添加 Service Worker 和 Manifest ```bash pnpm add next-pwa ``` --- ### 🟢 L3. 未启用 Gzip/Brotli 压缩 **建议**: Nginx 配置 ```nginx gzip on; gzip_vary on; gzip_types text/plain text/css application/json application/javascript; brotli on; brotli_types text/plain text/css application/json application/javascript; ``` --- ### 🟢 L4. 缺少 E2E 测试 **建议**: 集成 Playwright 或 Cypress ```typescript // tests/e2e/chat.spec.ts import { test, expect } from '@playwright/test'; test('chat flow', async ({ page }) => { await page.goto('/chat'); await page.fill('textarea', 'Hello'); await page.click('button[type="submit"]'); await expect(page.locator('.response')).toBeVisible(); }); ``` --- ### 🟢 L5-L14: 其他低危问题 **L5. 未配置 Prettier 自动格式化** ```json // .prettierrc { "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "none" } ``` **L6. 未使用 Husky + lint-staged** ```bash pnpm add -D husky lint-staged npx husky install ``` **L7. 未配置 Dependabot** ```yaml # .github/dependabot.yml version: 2 updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" ``` **L8. 未使用 Commitlint** ```bash pnpm add -D @commitlint/cli @commitlint/config-conventional ``` **L9. 缺少性能预算配置** ```javascript // next.config.js webpack(config) { config.performance = { maxAssetSize: 500000, maxEntrypointSize: 500000 }; return config; } ``` **L10. 未配置 Sentry 错误追踪** ```bash pnpm add @sentry/nextjs npx @sentry/wizard -i nextjs ``` **L11. 未实现请求重试机制** ```typescript async function fetchWithRetry(url, options, retries = 3) { for (let i = 0; i < retries; i++) { try { return await fetch(url, options); } catch (error) { if (i === retries - 1) throw error; await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i))); } } } ``` **L12. 未配置 robots.txt 和 sitemap.xml** ```typescript // pages/robots.txt.ts export default function Robots() { return null; } export async function getServerSideProps({ res }) { res.setHeader('Content-Type', 'text/plain'); res.write('User-agent: *\nAllow: /\n'); res.end(); return { props: {} }; } ``` **L13. 未使用 React DevTools Profiler** ```typescript // 生产环境添加性能监控 if (typeof window !== 'undefined' && window.location.search.includes('debug')) { import('react-devtools'); } ``` **L14. 缺少 API 文档自动生成** ```bash # 已有 OpenAPI 生成脚本 pnpm api:gen # 建议: 集成 Swagger UI ``` --- ## 四、修复优先级建议 ### 立即修复 (本周) 1. **H3**: SSE 客户端断开处理 (影响资源浪费和费用) 2. **H6**: React Hooks 内存泄漏扫描和修复 3. **H8**: 全局错误边界实现 ### 短期修复 (2周内) 4. **H1**: 工作流深度递归和并发控制 5. **H2**: MongoDB 连接池配置 6. **H4**: API 路由超时控制 7. **H7**: MongoDB 慢查询超时 ### 中期优化 (1月内) 8. **H5**: 变量注入安全防护 9. **H9**: 初始化错误处理优化 10. **M1-M10**: 中危性能优化项 ### 长期规划 (持续优化) 11. **L1-L14**: 低危问题和监控完善 12. 性能监控体系建设 13. 自动化测试覆盖率提升 --- ## 五、性能优化建议清单 ### 5.1 数据库层 - [ ] 配置 MongoDB 连接池参数 - [ ] 启用慢查询分析和超时控制 - [ ] 添加查询计划分析 - [ ] 优化索引同步策略 - [ ] 实现连接池监控 ### 5.2 应用层 - [ ] 工作流执行增加全局限制 - [ ] 实现 API 请求超时控制 - [ ] 优化错误处理和边界 - [ ] 修复 SSE 流资源泄漏 - [ ] 变量注入安全加固 ### 5.3 前端层 - [ ] React Hooks 依赖审查和修复 - [ ] 组件 memo 化优化 - [ ] 图片使用 Next.js Image 优化 - [ ] React Query 缓存策略配置 - [ ] 实现请求去重和缓存 ### 5.4 构建层 - [ ] 启用 SWC 完整优化 - [ ] 配置 Webpack 缓存优化 - [ ] 优化 getServerSideProps 使用 - [ ] 启用 Bundle Analyzer 监控 - [ ] 实验性启用 Turbopack ### 5.5 运维层 - [ ] 集成 Sentry 错误追踪 - [ ] 实现 Web Vitals 性能监控 - [ ] 配置 Lighthouse CI - [ ] 添加健康检查端点 - [ ] 实现日志聚合和分析 --- ## 六、监控和告警建议 ### 6.1 关键指标监控 ```typescript // 建议监控的指标 const metrics = { performance: { api_response_time: 'P95 < 500ms', page_load_time: 'P95 < 3s', workflow_execution_time: 'P95 < 30s' }, stability: { error_rate: '< 1%', uptime: '> 99.9%', mongodb_connection_errors: '< 10/hour' }, resource: { cpu_usage: '< 80%', memory_usage: '< 85%', mongodb_connection_pool: '< 90% utilization' } }; ``` ### 6.2 告警规则 ```yaml alerts: - name: high_error_rate condition: error_rate > 5% duration: 5m severity: critical - name: slow_api condition: api_p95_response_time > 2s duration: 10m severity: warning - name: memory_leak condition: memory_usage_growth > 10MB/min duration: 30m severity: warning - name: mongodb_slow_query condition: slow_queries > 50/min duration: 5m severity: critical ``` --- ## 七、总结 ### 问题统计 | 等级 | 数量 | 占比 | |------|------|------| | 🔴 高危 | 9 | 21.4% | | 🟡 中危 | 19 | 45.2% | | 🟢 低危 | 14 | 33.4% | | **总计** | **42** | **100%** | ### 核心问题域 1. **工作流引擎** (5个高危): 并发控制、内存管理、资源泄漏 2. **数据库层** (3个高危): 连接池、慢查询、索引 3. **API 层** (2个高危): 超时控制、错误处理 4. **前端性能** (8个中危): React 优化、资源加载、缓存策略 ### 预期收益 - **性能提升**: 修复后预期 API 响应时间降低 30-50% - **稳定性提升**: 工作流执行成功率提升至 99.5%+ - **资源优化**: 内存使用降低 20-30% - **用户体验**: 页面加载速度提升 40%+ ### 下一步行动 1. **Week 1**: 修复 H3, H6, H8 (立即影响稳定性) 2. **Week 2-3**: 修复 H1, H2, H4, H7 (核心性能优化) 3. **Week 4-8**: 逐步完成中危和低危优化 4. **持续**: 建立监控体系和自动化测试 --- **报告生成者**: Claude Code Analysis Agent **联系方式**: 如有疑问,请查看 `.claude/design` 目录获取详细设计文档