# Taro 小程序穷尽性能审计报告 > 日期: 2026-05-14 | 范围: apps/miniprogram/ (124 TS/TSX 文件, 66 页面) ## 审计维度 4 个并行审计 agent 覆盖:同步阻塞操作、依赖体积、API 调用+内存管理、渲染性能+导航。 ## 已修复的问题 ### CRITICAL (6 项 — 全部已修复) | # | 问题 | 文件 | 修复 | |---|------|------|------| | C1 | DataBuffer `while(true)` Sync Storage 无上限 | `ble/DataBuffer.ts` | 添加 `MAX_BUCKETS=20` 循环保护 | | C2 | DataBuffer.push 每次同步序列化大桶 | `ble/DataBuffer.ts` | 同上,限制桶数 | | C3 | `Math.max(...arr)` 展开大数组栈溢出风险 | `TrendChart/index.tsx`, `health/index.tsx` | 改用 `reduce` | | C4 | `responseCache` Map 无大小上限 | `services/request.ts` | 添加 `MAX_CACHE_SIZE=100` + LRU 淘汰 | | C5 | BLE 事件监听器累积(多次 connect 不移除旧监听) | `ble/BLEManager.ts` | 保存 handler 引用,connect 前先 off | | C6 | `navigateToLogin` 用 navigateTo 可能栈溢出 | `utils/navigate.ts` | 改为 `reLaunch` | ### HIGH (7 项 — 全部已修复) | # | 问题 | 文件 | 修复 | |---|------|------|------| | H1 | EcCanvas 死代码 + echarts 58MB 死依赖 | `components/EcCanvas/`, `package.json` | 删除文件 + 移除依赖 | | H2 | 访客首页每次 useDidShow 重新下载所有 banner 图片 | `pages/index/index.tsx` | 移除 downloadFile,直接用 URL + lazyLoad | | H3 | analytics 每次 track 两次 Sync Storage | `services/analytics.ts` | 内存队列 + 异步 `setStorage` | | H4 | `request.ts` getCacheKey 每次请求同步读 patientId | `services/request.ts` | 内存缓存 `cachedPatientId` | | H5 | 切换就诊人不清理请求缓存和 healthStore | `stores/auth.ts` | `setCurrentPatient` 中调用 `clearRequestCache` | | H6 | logout 不清理 healthStore/pointsStore | `stores/auth.ts` | logout 中调用 `healthStore.clearCache()` | | H7 | zod (5.5MB) + react-dom (4.4MB) 死依赖 | `package.json` | 移除两个未使用的依赖 | | H8 | 25 个页面 useDidShow 无条件全量刷新 | 多个页面 | 4 tabBar 页改 `useThrottledDidShow` + 子包页面同步更新 | | H9 | 12 处 `useAuthStore()` 无参数导致全 store 订阅 | 15 个文件 | 全部改为精确选择器模式(38 个订阅优化) | ### MEDIUM (已修复) | # | 问题 | 文件 | 修复 | |---|------|------|------| | M1 | settings 清缓存 17 次同步 Storage 操作 | `pkg-profile/settings/index.tsx` | 改为异步 `getStorage`/`clearStorage`/`setStorage` | | M2 | 6 个页面 JSX 渲染路径中调用 getStorageSync | 6 个 pkg-profile 页面 | 提取 `hasPatient` state,渲染时引用 state 而非 sync 调用 | | M5 | health/index.tsx indicatorCapsules/healthItems 每次 render 重建 | `pages/index/index.tsx` | `useMemo` 包裹,依赖 `todaySummary` 子字段 | | M6 | BLEManager 模块级单例导出 vs 页面独立创建双实例 | `services/ble/BLEManager.ts` | 移除 `export default new BLEManager()` | | M7 | device-sync useDidShow cleanup 不生效 | `pages/device-sync/index.tsx` | 清理逻辑移至 `useEffect` return | | M3 | AI 报告 sanitizeHtml 正则替换链 | `pages/ai-report/detail/index.tsx` | 合并 6 步 regex 为 2 步,合并 h1/h2/h3 为单步 | | M4 | doctor 子包 barrel re-export 全量引入 | 17 个 doctor 页面 | `import * as doctorApi` → 直接子模块具名导入 | | M8 | 聊天消息全量渲染无上限 | 2 个 consultation detail 页面 | 添加 `MAX_RENDER_MESSAGES=200` 渲染上限 + 截断提示 | ## 待后续修复的问题 ### HIGH (记录但未在本次修复) | # | 问题 | 文件 | 建议修复 | |---|------|------|----------| | H10 | 积分商城加载 100 商品只为查 1 个详情 | `pkg-mall/exchange` | 后端新增单品查询 API | | H11 | auth restore 启动路径 6 次同步 Storage 读取 | `stores/auth.ts` | 改异步 + 合并读取 | ## 包体积审计 | 指标 | 值 | |------|-----| | 编译产物总大小 | 1.4 MB | | 主包 (taro + app + vendors + common) | ~380 KB | | 最大子包 (doctor, 18 页面) | 268 KB | | 移除的死依赖 | echarts (58MB) + zod (5.5MB) + react-dom (4.4MB) | ## 正面发现 - Taro 4.x 编译产物干净,无 crypto-js 残留 - 所有列表页使用页面级 `useReachBottom` 而非 ScrollView(性能最佳实践) - TabBar 图标均为 334 bytes 极简图标 - app.tsx 的 analytics 定时器和事件监听 cleanup 正确 - 无内联 base64 图片、无 require 图片资源 - 文章列表 Image 已正确设置 `lazyLoad` ## 编译验证 - `taro build --type weapp` 编译成功 (10.46s) - 所有修复已确认包含在编译产物中