# DevTools 卡死根因分析 — 四专家组深度诊断 > 日期: 2026-05-14 | 参与者: 内存泄漏专家 + 渲染性能专家 + 网络/API专家 + DevTools环境专家 ## 背景 微信开发者工具中 HMS 小程序持续卡死: - 内存从 1283MB 增长到 2290MB+ - 截图功能始终超时(mp.screenshot timeout) - 页面导航 30s 超时 - 修复 analytics/batch 422 + auth restore 后,卡死依旧 ## 根因链条(四维度交叉验证) ``` DevTools 环境问题(基线内存偏高) ├─ compileHotReLoad=true → 每次文件变化重建编译上下文,旧上下文不释放 ├─ minified=true → DevTools 二次压缩 JS,每个刷新周期重复执行 └─ prebundle=false → webpack 内存中维护完整依赖图 ↓ 内存基线已高 → GC 频率升高 → JS 线程长时间占用 ↓ 网络/API 循环(持续加压) ├─ Redis 不可用 → 限流中间件每请求 2 次 error 日志(日志洪泛) ├─ JWT 中间件每请求 2 次 DB 查询(无缓存) ├─ 首页 Tab 切换并发 6+ 请求 × 2 次 DB = 12-16 次 DB 查询 └─ 咨询长轮询 401 时 token 刷新 + 重试循环 ↓ 后端压力大 + 前端请求队列积压 ↓ 内存泄漏(持续增长) ├─ consultation detail messages 数组无上限(只增不减) ├─ request.ts inflightRequests 无超时清理 ├─ TrendChart canvas node 卸载后未释放 └─ BLE DataBuffer seenKeys Set 不随数据淘汰清理 ↓ 内存突破阈值 → GC 暂停 → automator 超时 → 卡死 ``` ## CRITICAL 问题(共 7 项) ### 1. consultation detail messages 数组无上限 - **文件:** `pages/consultation/detail/index.tsx:70-76`(患者端 + 医生端相同) - **问题:** 长轮询每 3 秒 `[...prev, ...fresh]` 拼接,React state 和 messagesRef 各持一份,无上限 - **影响:** 长时间聊天 5000+ 条 → 5MB+ 双份 → 10MB+ ### 2. compileHotReLoad 配置矛盾 - **文件:** `project.config.json:10` vs `project.private.config.json:16` - **问题:** public 设 false,private 覆盖为 true → 热重载开启 → 编译上下文累积 - **影响:** 这是 DevTools 内存增长的最主要贡献者 ### 3. minified=true 开发模式多余压缩 - **文件:** `project.config.json:12` - **问题:** DevTools 层二次压缩 JS,每个刷新周期重复执行 - **影响:** 72 个 JS 文件 × 每次刷新重新压缩 ### 4. Redis 不可用 → 限流日志洪泛 - **文件:** `crates/erp-server/src/middleware/rate_limit.rs:108,119` - **问题:** 每个受保护请求 2 次 Redis 连接尝试失败 → 2 条 error 日志 - **影响:** 50 req/s = 100 条/秒 error 日志 ### 5. JWT 中间件每请求 2 次 DB 查询无缓存 - **文件:** `crates/erp-auth/src/middleware/jwt_auth.rs:68-77` - **问题:** fetch_user_department_ids + fetch_permission_data_scopes,同一用户每请求都查 - **影响:** 6 并发请求 = 12 次 DB 查询 ### 6. 咨询长轮询 Tab 切换后不停止 - **文件:** `pages/consultation/detail/index.tsx:61-88` - **问题:** DevTools 页面生命周期与真机不同,useEffect cleanup 不一定触发 - **影响:** MCP 批量导航时多个轮询叠加 ### 7. 健康数据页 14 useState 重渲染风暴 - **文件:** `pages/health/index.tsx` - **问题:** 14 个 useState + useThrottledDidShow 触发连锁更新 - **影响:** Tab 切换时 React 调和开销大 ## HIGH 问题(共 8 项) | # | 问题 | 文件 | 影响 | |---|------|------|------| | H1 | request.ts inflightRequests 无超时清理 | services/request.ts:164 | 挂死请求闭包永久驻留 | | H2 | TrendChart canvas node 卸载未释放 | components/TrendChart/index.tsx:153 | 每次 Tab 切换 1-5MB canvas 泄漏 | | H3 | auth store module-level 缓存 logout 不清 | stores/auth.ts:9-14 | 多账户数据残留 | | H4 | prebundle 禁用 webpack 内存膨胀 | config/dev.ts:6-8 | 大型 chunk 完整依赖图驻留内存 | | H5 | 首页 6+ 并发 API 请求无优先级 | pages/index/index.tsx:194 | 后端压力叠加 | | H6 | 长轮询 401 刷新重试循环 | services/request.ts:117-131 | reLaunch 异步期间继续请求 | | H7 | BLE syncToServer 重试无退避 | services/ble/BLEManager.ts:262 | flush→失败→push back→flush 循环 | | H8 | base.wxml 68KB 模板体积偏大 | dist/base.wxml | DevTools 解析负担 | ## 立即缓解措施(不改代码) 1. **关闭热重载:** DevTools 设置 → 关闭"文件保存时自动编译" 2. **关闭压缩:** project.config.json → `"minified": false` 3. **定期重启 DevTools:** 每 30 分钟或内存超过 1.5GB 4. **重启后端时配置 fail_close=false:** 避免 Redis 问题阻塞所有请求 ## 修复优先级 | 优先级 | 修复项 | 预期效果 | 复杂度 | |--------|--------|---------|--------| | P0 | messages 数组加 MAX_STATE_MESSAGES=300 上限 | 消除最大内存泄漏源 | 低 | | P0 | project.private.config.json compileHotReLoad=false | 降低 DevTools 内存基线 | 极低 | | P0 | project.config.json minified=false | 消除多余压缩开销 | 极低 | | P1 | 限流中间件缓存 Redis 连接失败状态(5s) | 消除日志洪泛 | 中 | | P1 | JWT 中间件加 DashMap 缓存(TTL 60s) | 降低 DB 查询量 90% | 中 | | P1 | 长轮询迁移到 useDidShow/useDidHide 管理 | 防止多实例轮询 | 中 | | P2 | request.ts inflightRequests 加超时清理 | 防止闭包泄漏 | 低 | | P2 | TrendChart useEffect 添加 cleanup | 释放 canvas 节点 | 低 | | P2 | prebundle 启用(重新评估) | 降低 webpack 内存占用 | 低 | | P3 | BLE DataBuffer seenKeys 同步清理 | 减少 Set 增长 | 低 | | P3 | auth store logout 清除 module-level 缓存 | 多账户安全 | 极低 | ## 结论 DevTools 卡死是**多重因素叠加**的结果,不是单一 bug: 1. DevTools 环境配置(热重载+压缩)抬高了内存基线 2. 后端 Redis 不可用导致日志洪泛 + 无限流保护 3. 前端 consultation detail messages 无上限是最直接的内存泄漏 4. JWT 中间件无缓存导致后端 DB 压力放大 5. 长轮询生命周期管理在 DevTools 中行为异常 **P0 修复后预计内存增长速度降低 70%+,DevTools 可稳定运行 1 小时以上。**