Files
hms/docs/discussions/2026-05-14-devtools-freeze-root-cause.md
iven 8f353946e1 fix(mp): T40 UI 审计修复 — 28 项设计系统合规 + 安全加固 + 讨论记录
T40 UI 审计修复(60 页面全覆盖):
- 新增 $acc-d/$wrn-d 渐变中间色变量,修复首页轮播渐变硬编码
- 替换 8 处裸 white 为 $white 设计变量(5 个 SCSS 文件)
- 修复 7 处触摸目标 40/44px → 48px(健康/消息/咨询/预约/首页)
- 3 页面新增 Loading 状态(体征录入/个人中心/就诊人添加)
- statusTag 移除硬编码布局值,改用 SCSS mixin 控制
- 医生端 14 页面架构 Hook 层补充(useThrottledDidShow 替换 useEffect)
- 移除 action-inbox 未使用 import

安全 P0 修复:
- JWT 中间件加固:token 类型校验 + 过期预检 + 类型别名简化
- 速率限制增强:滑动窗口 + 暴力破解防护
- analytics handler 错误处理完善

文档:
- T40 审计报告(24 PASS / 36 PASS_WITH_ISSUES / 0 NEEDS_WORK)
- 5 份 DevTools/性能审计讨论记录
- wiki 症状导航 + 小程序章节更新
2026-05-14 23:12:54 +08:00

6.1 KiB
Raw Blame History

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 设 falseprivate 覆盖为 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 小时以上。