记录一次旧项目的优化过程
最近着手了部门一个老网站的性能优化,
此网站的主要问题有:
- 性能太差,接口响应时间很慢
- 部署复杂,多次转发
分析之后我发现:
-
大量接口直接查询某个表中的所有数据、没有使用分页查询,导致返回的数据量过大,降低了接口响应速度和前端渲染速度(甚至教师预约界面的渲染会让整个电脑都顿时变得卡顿),返回了大量不必要的数据
-
筛选条件不足
-
一些数据在前端处理、收集结果集(比如前端接收到所有课程的数据之后,逻辑处理出已结束的课程的结果集 然后在一个页面中渲染,降低了性能)
优化接口响应时间
1.缩小查询范围
version: 1.0.1 ——修改接口 限定查询范围、减少不必要的数据返回 拉高数据量 降低性能
原项目中/course、/course/sign、/activity、/activity/sign等接口都默认查询所有的课程/活动/,导致数据量太大(有的接口甚至一次返回几千条数据),前端渲染慢、后端响应慢
而后我将部分接口改成分页查询、增加了查询条件,减少了不必要的数据返回,提高了响应速度和渲染速度
2.SQL性能优化
改成version:1.0.1之后,我开启了慢查询日志,并尝试进行sql优化(这里主要对我写的语句都做了优化,因为此老项目大量使用mybatisplus,大量sql语句都不是直接可视化的):
-
查询已经结束的活动的结果集太大,不适合索引
-
优化了联表查询,以小表为驱动,并做了测试

改完后,sql执行时间:0.023sec ->0.014s (status = 3时)(navicat测试)


改完后,sql执行时间:0.003 -> 0.002s(status = 2时)(Navicat测试)


改完后,sql执行时间:0.2sec -> 0.04sec

-
继续优化 order by 语句
ORDER BY us.course_id DESC改为ORDER BY c.id DESC(使用索引)(0.141s -> 0.001s) -
由于深分页在这个网站中几乎不会被查询,所以暂时不使用覆盖索引+子查询优化分页查询
-
查看积累几天的慢查询日志之后,我发现原项目速度慢的sql语句主要有
text//日志几乎全是这条 SELECT id,academy,`usage`,name,phone,date,time,status,extra,start_time,end_time,room_id,room,teacher_name,speaker,user_num,submit_time FROM reservation_view ORDER BY status ASC;text//这条占比也不小 SELECT id,openid,student_name,student_id,academy,klass,phone,qq,course_id,create_time,category,time,teacher_name,date,content,place,deadline,student_count,course_name,course_status,user_sign_status,check_status,check_time,start_time,end_time FROM user_sign_view ORDER BY course_id ASC;text//出现频率较少 SELECT id,name,phone,qq,student_id,academy,klass,activity_id,openid,theme,activity_name,category,activity_status,activity_sign_status FROM activity_sign_view; SELECT id,category,time,teacher_name,date,content,place,deadline,student_count,name,status,start_time,end_time FROM course;这里也可以看出来学长(们)联查基本用的视图,且没做分页
-
重新部署之后,我又看了积累几天的慢查询日志,不过没有发现慢查询语句
比较遗憾的是该项目不大,没能用上所有的优化技巧
3.Redis
想要提升性能,肯定会想到redis,但是由于优化完前两步之后发现性能已经足够、加上本人时间紧张,以及此后端和小程序关联,暂时不加redis
反映性能的指标
浏览器的几个指标
网络-时间模块

| 时间段 | 含义 |
|---|---|
| DNS 查找 | 解析域名到 IP 的时间 |
| TCP 连接 / SSL | 建立连接的时间(HTTPS 会包含 TLS 握手) |
| 发送请求 | 客户端发送 HTTP 请求头的时间(通常很快) |
| 等待服务器响应(TTFB) | ⚠️ 最关键!从发送请求到收到第一个字节的时间。反映后端处理速度 |
| 下载内容 | 接收响应体的时间(与数据大小和带宽有关) |
重点关注:
✅ 1. 减少 TTFB(Time To First Byte)
- 检查后端代码是否有耗时操作(如慢 SQL 查询、循环调用多个 API)
- 是否有缓存机制?例如 Redis 缓存 JSON 数据?
- 是否可以异步加载部分数据?
✅ 2. 优化资源加载
content-all.css和fonts.css被多次加载,可能是因为重复引入或未合并。- 可以考虑:
- 合并 CSS 文件
- 使用 CDN 加速静态资源
- 开启 Gzip 压缩
✅ 3. 分析其他接口
- 多次刷新页面,看不同请求的 TTFB 是否稳定
- 对比
course、sign、zh_CN.json等接口的响应时间,找出最慢的几个
性能模块

Google 官方推荐的三大核心指标:
| 指标 | 全称 | 含义 | 优化目标 |
|---|---|---|---|
| LCP | Largest Contentful Paint | 渲染最大内容元素的时间(如主图、标题) | ≤ 3 秒 |
| FID | First Input Delay | 用户首次交互(点击、输入)到浏览器实际响应的延迟 | ≤ 100 毫秒 |
| CLS | Cumulative Layout Shift | 页面加载过程中布局意外偏移的累积分数(如图片突然撑开页面) | ≤ 0.1 |
改动前后的接口性能测试
答疑坊页面
/course

/course/sign

LCP

改动后
/course/completed

/course/sign

/course/uncompleted

LCP

荟知坊 & 志趣坊 页面
/activity

/room

/activity/sign

LCP

改动后
/activity/all

/room

/activity/completed

/activity/sign/bystatus

LCP

教师预约 页面
/reservation

LCP

改动后
/reservation/reservationv2

LCP

全校性选修课 页面
/course/by/elecourse

LCP

改动后
/course/by/elecoursev2

LCP

评论 (0)
暂无评论,快来抢沙发吧!