Next.js SSR实战排障:把首屏从2.8秒压到900ms的全栈改造流程
Chapter 1:OK so,先把慢点抓出来,不要凭感觉优化
兄弟们开机!我是 eccfy,今天我们不讲玄学,直接录屏实战:一个 Next.js 页面首屏 2.8 秒、接口 TTFB 1.4 秒,接下来我把它压到 900ms 左右。你跟着做,适合搜索“Next.js SSR教程”“Next.js全栈开发怎么用”“Next.js性能优化实战”的同学。
先跑本地基准,屏幕左边终端、右边 Chrome DevTools,走起:
npm create next-app@latest next-ssr-demo
cd next-ssr-demo
npm run dev
npm run build
npm start
打开 DevTools 的 Network,勾选 Disable cache,刷新 3 次,记录三个数字:Document 的 TTFB、LCP、接口耗时。我这边未优化前:TTFB 1420ms,LCP 2.8s,HTML 体积 92KB。注意,如果你在查“油管怎么看”这类跨境内容时发现页面慢,先别急着怪网络,SSR 数据源、服务端缓存、图片体积同样会拖垮首屏。
Chapter 2:Now watch this,SSR 数据获取和缓存这样拆
Next.js App Router 里,默认 Server Component 很香,但别把所有接口都塞进一个页面 await。接下来我们把“必须首屏展示”和“可延迟加载”拆开。
首屏数据用服务端 fetch,并设置 revalidate。
// app/page.tsx
async function getPosts() {
const res = await fetch('http://localhost:3000/api/posts', {
next: { revalidate: 60 }
});
if (!res.ok) throw new Error('fetch posts failed');
return res.json();
}
export default async function Page() {
const posts = await getPosts();
return <main>{posts.map((p:any)=><article key={p.id}>{p.title}</article>)}</main>;
}
慢接口不要阻塞 SSR,用 Suspense 分区。
// app/page.tsx
import { Suspense } from 'react';
import SlowPanel from './SlowPanel';
export default function Page() {
return (
<>
<Hero />
<Suspense fallback={<p>加载统计中...</p>}>
<SlowPanel />
</Suspense>
</>
);
}
这里的核心原因很简单:SSR 不是把所有东西都提前算完,而是把影响首屏判断的内容优先返回。像“翻墙软件评测数据”“免费VPN速度排行”这种经常变、还可能依赖第三方接口的数据,更适合设置 30-300 秒缓存,或者客户端延迟请求。
Chapter 3:API Route、图片和验证,现场看结果
接下来上 API Route。不要在每次请求里重复创建数据库连接,演示用 Prisma 或 pg 都一样,连接实例要复用:
// lib/db.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma?: PrismaClient };
export const db =
globalForPrisma.prisma ?? new PrismaClient({ log: ['error', 'warn'] });
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = db;
图片别直接丢 2MB 原图。用 Next Image,设置尺寸,开启现代格式:
// next.config.js
module.exports = {
images: {
formats: ['image/avif', 'image/webp']
}
};
再来一个部署前检查清单,兄弟们暂停抄一下:
npm run build 看有没有动态渲染误判。
ANALYZE=true npm run build 检查大包,超过 200KB 的客户端组件优先拆。
Chrome Lighthouse 跑移动端,LCP 目标小于 2.5s。
用 curl 看 TTFB:
curl -o /dev/null -s -w "TTFB:%{time_starttransfer}\nTotal:%{time_total}\n" http://localhost:3000
我这次本机 Node 20、Next.js 14 测试,优化后 TTFB 从 1420ms 降到 380ms,LCP 从 2.8s 到 0.9s,HTML 从 92KB 到 41KB。怎么验证修好了?清空浏览器缓存,连续刷新 5 次;接口日志里没有重复建连;curl 的 TTFB 稳定低于 500ms;Lighthouse Performance 至少 85 分以上。
免费方案优先用 Next.js 官方缓存、Node 内置性能日志、Chrome DevTools;如果你的团队还需要稳定访问海外文档、包源或视频教程,Roxi 也只是可选网络工具之一:wizzegroup.com。OK,今天这波如果帮你把首屏打下来了,评论区贴你的前后数据,我们下一期继续现场拆项目!