Next.js SSR页面加载时长超10秒,寻求优化方案
问题解答
是否正常?
完全不正常。SSR冷启动确实会因为服务端渲染、鉴权校验比静态页面慢,但24.84秒的总时长已经严重超出合理范围——正常优化后的SSR冷启动一般控制在1-3秒内,单次Prisma查询、tRPC请求都不该跑到10秒以上。
优化方案
一、初始文档加载(Prisma查询)优化
- 数据库查询调优
- 排查Prisma查询是否有隐性问题:哪怕你说只有一次查询,也要确认是不是关联了其他模型却没加
include/select导致隐式N+1查询。可以开Prisma的查询日志(log: ['query'])看实际执行的SQL,或者用prisma.$queryRaw写原生SQL对比耗时。 - 加索引:如果查询是基于用户ID、角色这类字段,给数据库对应字段建索引,避免全表扫描拖慢速度。
- 精简返回字段:用
select只拿需要的属性,别返回整个模型的所有字段,减少数据序列化和传输的开销。
- 排查Prisma查询是否有隐性问题:哪怕你说只有一次查询,也要确认是不是关联了其他模型却没加
- 服务端冷启动优化
- 检查部署环境的实例冷启动:如果是云服务,可能实例休眠后唤醒慢,试试定时发请求预热实例,或者换支持更快冷启动的Runtime(比如Edge Runtime)。
- 缓存鉴权结果:鉴权逻辑如果依赖数据库或外部服务,把用户鉴权后的信息短时间缓存到Redis里,别每次请求都重复查。
二、tRPC请求优化
- 合并重复请求
- 两个
user.me请求纯纯冗余,直接在tRPC里把多个请求合并成一个批量调用,或者在服务端写个复合接口,一次性返回<Preferences />需要的所有数据,省掉多次请求的额外开销。
- 两个
- 优化tRPC resolver逻辑
- 看看
user.me的resolver有没有重复鉴权、重复查库,或者有没有同步阻塞的操作(比如同步IO、大量计算),尽量改成异步非阻塞处理。 - 加响应缓存:用户偏好这类不怎么变的数据,在resolver里用Redis或内存缓存存起来,设个合理的过期时间,别每次都查数据库。
- 看看
- 调整组件加载时机
- 如果业务允许,把
<Preferences />改成客户端组件,等页面核心内容加载完再发请求,不阻塞初始渲染;或者用Suspense包起来做流式渲染,让用户先看到核心内容,偏好组件慢慢加载。
- 如果业务允许,把
三、通用SSR优化
- 开启流式渲染
- 用框架的流式渲染功能(比如Next.js的流式输出、React 18的Streaming SSR),把页面拆成片段逐步发给客户端,用户能更早看到内容,感知加载速度快很多。
- 代码分割
- 给页面和组件做代码分割,只加载当前页面必需的代码,减少服务端渲染和客户端 hydration 的时间。
- 压缩与缓存
- 开启Gzip/Brotli压缩服务端返回的HTML和静态资源,减小传输体积。
- 给JS、CSS、图片这类静态资源设置合理的缓存策略,避免重复加载。
内容的提问来源于stack exchange,提问作者Herbie Vine
相关产品推荐
相关产品推荐

