最近着手了部门一个老网站的性能优化,

此网站的主要问题有:

  • 性能太差,接口响应时间很慢
  • 部署复杂,多次转发

分析之后我发现:

  • 大量接口直接查询某个表中的所有数据、没有使用分页查询,导致返回的数据量过大,降低了接口响应速度和前端渲染速度(甚至教师预约界面的渲染会让整个电脑都顿时变得卡顿),返回了大量不必要的数据

  • 筛选条件不足

  • 一些数据在前端处理、收集结果集(比如前端接收到所有课程的数据之后,逻辑处理出已结束的课程的结果集 然后在一个页面中渲染,降低了性能)

优化接口响应时间

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.cssfonts.css 被多次加载,可能是因为重复引入或未合并。
  • 可以考虑:
    • 合并 CSS 文件
    • 使用 CDN 加速静态资源
    • 开启 Gzip 压缩

✅ 3. 分析其他接口

  • 多次刷新页面,看不同请求的 TTFB 是否稳定
  • 对比 coursesignzh_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