flnxi-Wu/docs/archive/代码优化总结.md
WuYongJie 63ec6b7dfb fix: 修复排行榜按钮消失、tag排序和输入框浅色模式问题
1. 排行榜悬浮窗关闭后小按钮消失问题
   - 修复面板居中模式关闭时按钮位置错误
   - 保存并恢复按钮的居中状态

2. 首页tag按钮按素材数量排序
   - 添加按素材数量降序排序逻辑

3. 上传弹窗输入框浅色模式文字不可见
   - 添加 text-slate-900 确保浅色模式下文字可见
   - 添加 placeholder 样式确保占位符正确显示
2025-12-14 21:41:29 +08:00

6.6 KiB
Raw Blame History

代码优化总结

根据《架构设计与编码规范.md》和《性能优化指南.md》,已完成以下优化:

1. 性能优化

1.1 数据库查询优化

N+1 查询问题修复

  • rankings API (app/api/rankings/route.ts)

    • 下载排行榜和点赞排行榜:从 N+1 查询改为单次 SQL 聚合查询
    • 使用 INNER JOIN 一次性获取用户信息和统计数据
  • categories API (app/api/categories/route.ts)

    • 从每个分类单独查询素材数量改为单次 SQL 聚合查询
    • 使用 GROUP BY 一次性获取所有分类的素材数量
  • scenes API (app/api/scenes/route.ts)

    • 从每个场景单独查询素材数量改为单次 SQL 聚合查询
    • 支持按店铺筛选,仍使用单次查询

查询字段优化

  • system-settings API (app/api/system-settings/route.ts)

    • 使用 select 只查询必要字段,避免返回敏感信息(如密码)
    • 实现 1 分钟缓存,减少数据库查询
  • admin/system-status API (app/api/admin/system-status/route.ts)

    • 优化并行查询,减少查询次数
    • 使用 SQL 聚合查询替代多次 count() 调用
    • 限制最近活动数据为 10 条,减少数据传输
  • materials/stats API (app/api/materials/stats/route.ts)

    • 从加载所有素材的 createdAt 改为 SQL 聚合查询
    • 使用 EXTRACT(YEAR/MONTH) 在数据库层面完成分组

1.2 分页实现

  • admin/users API (app/api/admin/users/route.ts)

    • 添加分页支持(默认 20 条,最大 100 条)
    • 返回分页信息(总数、总页数等)
  • danmaku API (app/api/danmaku/route.ts)

    • 限制最大返回数量为 100 条
    • 只返回必要字段,保护用户隐私(不返回 userId)

1.3 缓存机制

  • 创建缓存工具 (lib/cache.ts)

    • 实现简单的内存缓存(单例模式)
    • 支持 TTL(默认 1 分钟)
    • 自动清理过期项
    • 限制最大缓存项数(1000 项)
  • system-settings API 缓存

    • GET 请求使用缓存(1 分钟 TTL)
    • PUT 请求自动清除缓存,确保数据一致性

1.4 SSE 优化

  • danmaku API SSE (app/api/danmaku/route.ts)
    • 减少初始数据量(从 50 条减少到 30 条)
    • 增加轮询间隔(从 1 秒增加到 2 秒),减少数据库压力
    • 使用 lastDanmakuId 避免重复推送
    • 改进错误处理,出错时自动关闭连接,避免资源泄漏

2. 代码质量改进

2.1 错误处理

  • 统一错误日志格式,添加 API 标识前缀(如 [SystemSettings]、[MaterialStats])
  • 改进错误信息,开发环境返回详细错误,生产环境返回通用错误

2.2 资源管理

  • SSE 连接正确清理(clearInterval 和 controller.close())
  • 错误时自动关闭连接,避免资源泄漏

2.3 数据安全

  • 弹幕 API 不返回 userId,保护用户隐私
  • 系统设置 API 使用 select 避免返回敏感字段

3. 符合规范检查

✅ 性能开销优先

  • 所有列表 API 实现分页
  • 使用 SQL 聚合查询替代多次查询
  • 实现缓存机制减少数据库查询
  • 优化数据传输量(只返回必要字段)

✅ 稳定性优先

  • 改进错误处理
  • 资源正确清理
  • SSE 连接异常时自动关闭

✅ 易于部署

  • 缓存机制为内存缓存,无需额外配置
  • 所有优化都是代码层面的,无需修改部署配置

4. 第二轮优化(已完成)

4.1 修复更多 N+1 查询问题

  • platforms API (app/api/platforms/route.ts)
    • 从每个平台单独查询素材数量改为单次 SQL 聚合查询
    • 统一错误日志格式

4.2 优化 materials API

  • materials API (app/api/materials/route.ts)

    • 修复重复代码问题
    • 使用 select 只查询必要字段
    • 限制最大分页大小为 100
    • 并行查询总数和数据,提升性能
    • 优化点赞状态查询(只在有数据时查询)
  • materials/[id] API (app/api/materials/[id]/route.ts)

    • 使用 select 只查询必要字段
    • 统一错误日志格式

4.3 优化 rankings API

  • rankings API (app/api/rankings/route.ts)
    • 贡献排行榜改为 SQL 聚合查询,保持与其他排行榜一致
    • 统一错误日志格式

4.4 优化 invitations API

  • invitations API (app/api/invitations/route.ts)
    • 添加分页支持(默认 20 条,最大 100 条)
    • 使用 select 只返回必要字段,保护隐私
    • 并行查询总数和数据
    • 统一错误日志格式

5. 待优化项(可选)

5.1 文件上传优化

  • 当前使用 arrayBuffer() 将整个文件加载到内存
  • 建议:对于大文件(>100MB),考虑使用流式处理
  • 注意:Next.js 的限制可能需要在服务器端实现

5.2 并发控制

  • 文件上传 API 当前没有并发限制
  • 建议:添加并发上传限制,避免服务器过载

5.3 数据库索引

  • 建议检查以下字段是否有索引:
    • materials.category_name
    • materials.scene_name
    • materials.user_id
    • materials.created_at
    • materials.platform_name
    • users.department
    • users.role

6. 性能提升预期

  • N+1 查询修复:查询时间从 O(n) 降低到 O(1)
    • rankings API:3 个排行榜全部使用 SQL 聚合查询
    • categories/scenes/platforms API:从 N 次查询减少到 1 次
  • 缓存机制:系统设置查询响应时间减少 90%+(缓存命中时)
  • 分页实现:大数据量时内存使用减少 80%+
    • materials API:限制最大分页为 100
    • admin/users API:支持分页
    • invitations API:支持分页
  • 并行查询:materials API 和 invitations API 使用并行查询,响应时间减少 30-50%
  • SSE 优化:数据库查询频率减少 50%
  • 查询字段优化:所有 API 使用 select 只查询必要字段,数据传输量减少 20-40%

7. 注意事项

  1. 缓存一致性:系统设置更新时会自动清除缓存,确保数据一致性
  2. 单实例部署:当前缓存实现为内存缓存,仅适用于单实例部署
  3. 数据库表名:SQL 查询使用 PostgreSQL 的实际表名(snake_case),而非 Prisma 模型名
  4. 向后兼容:
    • materials API:保持原有响应格式
    • invitations API:响应格式有变化,从数组改为对象(包含 invitations 和 pagination)
    • admin/users API:响应格式有变化,从数组改为对象(包含 users 和 pagination)
    • 其他 API:保持向后兼容
  5. 分页限制:所有分页 API 最大分页大小限制为 100,防止恶意请求
  6. 错误日志:所有 API 统一使用 [API名称] 方法名 error: 格式,便于日志分析和调试