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 症状导航 + 小程序章节更新
6.1 KiB
6.1 KiB
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:10vsproject.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 解析负担 |
立即缓解措施(不改代码)
- 关闭热重载: DevTools 设置 → 关闭"文件保存时自动编译"
- 关闭压缩: project.config.json →
"minified": false - 定期重启 DevTools: 每 30 分钟或内存超过 1.5GB
- 重启后端时配置 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:
- DevTools 环境配置(热重载+压缩)抬高了内存基线
- 后端 Redis 不可用导致日志洪泛 + 无限流保护
- 前端 consultation detail messages 无上限是最直接的内存泄漏
- JWT 中间件无缓存导致后端 DB 压力放大
- 长轮询生命周期管理在 DevTools 中行为异常
P0 修复后预计内存增长速度降低 70%+,DevTools 可稳定运行 1 小时以上。