1. 排行榜悬浮窗关闭后小按钮消失问题 - 修复面板居中模式关闭时按钮位置错误 - 保存并恢复按钮的居中状态 2. 首页tag按钮按素材数量排序 - 添加按素材数量降序排序逻辑 3. 上传弹窗输入框浅色模式文字不可见 - 添加 text-slate-900 确保浅色模式下文字可见 - 添加 placeholder 样式确保占位符正确显示
6.6 KiB
6.6 KiB
代码优化总结
根据《架构设计与编码规范.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_namematerials.scene_namematerials.user_idmaterials.created_atmaterials.platform_nameusers.departmentusers.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. 注意事项
- 缓存一致性:系统设置更新时会自动清除缓存,确保数据一致性
- 单实例部署:当前缓存实现为内存缓存,仅适用于单实例部署
- 数据库表名:SQL 查询使用 PostgreSQL 的实际表名(snake_case),而非 Prisma 模型名
- 向后兼容:
- materials API:保持原有响应格式
- invitations API:响应格式有变化,从数组改为对象(包含
invitations和pagination) - admin/users API:响应格式有变化,从数组改为对象(包含
users和pagination) - 其他 API:保持向后兼容
- 分页限制:所有分页 API 最大分页大小限制为 100,防止恶意请求
- 错误日志:所有 API 统一使用
[API名称] 方法名 error:格式,便于日志分析和调试