SleepDr 案例研究:WordPress 迁移至 Next.js(Lighthouse 35→94)
上一季度,我们接手了一个项目,完美诠释了为什么 WordPress 并不总是合适的选择。SleepDr.com —— 一个拥有 228 篇博客文章、一个联系表单以及移动端 Lighthouse 得分为 35 的睡眠健康内容网站 —— 迫切需要我们帮助提升速度。他们的自然流量已经下滑了好几个月。谷歌 2026 年 3 月核心更新引入了整体网站范围内的核心网页指标评分后,他们被重创。每一篇缓慢的博客文章都在拖累整个域名的排名。
我们将他们迁移到了 Next.js 15 + Payload CMS 3 + Supabase + Vercel。结果是:移动端 Lighthouse 94,桌面端 99。六周内有机流量恢复。这是我们如何实现这一切的完整故事 —— 每一项优化、每一个指标、每一个决策 —— 这样你可以将相同的思路应用到自己的项目中。
目录
- 迁移前:WordPress 为什么在毁掉 SleepDr
- 迁移技术栈:我们为什么选择这些
- 迁移前后:数据对比
- 优化 1:图像优化(LCP -3s)
- 优化 2:字体优化(FCP -1.5s)
- 优化 3:JavaScript 精简(TBT 1200ms → 50ms)
- 优化 4:服务端渲染和边缘部署(TTFB -85%)
- 优化 5:第三方脚本管理
- 优化 6:CSS 优化(800KB → 35KB)
- 分步检查清单
- 2026 年核心网页指标对你的网站意味着什么
- 常见问题

迁移前:WordPress 为什么在毁掉 SleepDr
SleepDr 的 WordPress 设置是积累技术债的教科书式例子。三年来,他们已经安装了 34 个插件。主题加载了 jQuery 加上两个额外的 JavaScript 库。每个页面请求都要访问一次 MySQL 数据库,即时生成 HTML,并通过已经不堪重负的共享主机计划提供未优化的图像。
以下是初始移动端 Lighthouse 审计的结果:
- 总体得分:35(红色,不及格)
- FCP:4.2 秒
- LCP:6.8 秒 —— 几乎是"良好"阈值的三倍
- CLS:0.28 —— 由于广告、没有指定尺寸的图像和网页字体加载,布局到处跳动
- TBT:1,200ms —— 主线程被锁定超过一秒
- TTFB:2.1 秒 —— 服务器本身就很慢,甚至在任何内容渲染之前
这个网站不仅慢。它对移动设备上的用户极其不友好。由于 Google 的 Lighthouse 移动模拟模拟的是中端手机在节流 4G 连接上的表现,得分反映了在不理想条件下真实用户经历的情况。
谷歌 2026 年 3 月核心更新推出后,引入了整体 CWV 评分 —— 按照整个域名而非按页面汇总性能 —— SleepDr 的 228 篇缓慢博客文章正在从整体上毒害他们的排名。早期数据显示受影响网站的流量下降了 20-35%。SleepDr 看到大约 30% 的下降。
必须做出改变。
迁移技术栈:我们为什么选择这些
我们没有选择这个技术栈因为它很时尚。我们选择它是因为每一个部分都解决了 SleepDr 遇到的一个具体问题。
- Next.js 15(App Router):混合渲染。博客文章的静态生成,需要时的服务端渲染。React 服务器组件以最小化客户端 JavaScript。这是我们的拿手好戏 —— 我们已经通过我们的 Next.js 开发实践 构建了数十个项目。
- Payload CMS 3:自托管无头 CMS,给了 SleepDr 的内容团队他们习惯的与 WordPress 相同的编辑体验,但没有臃肿。我们处理很多 无头 CMS 实现,Payload 3 已成为我们处理内容密集型网站的首选。
- Supabase:PostgreSQL 数据库,具有实时功能。处理联系表单提交、分析事件和任何动态数据。
- Vercel:边缘部署。网站从最靠近用户的节点提供。TTFB 变得几乎可以忽略。
总迁移耗时 7 周。内容迁移 —— 所有 228 篇文章及其图像、元数据和 URL 结构 —— 花费了大约 2 周。我们写了一个自定义脚本来从 WordPress REST API 拉取内容,进行转换,并推送到 Payload CMS。
迁移前后:数据对比
这是完整的分解。这些是 Lighthouse 移动端得分,这是真正故事所在的地方。
| 指标 | 迁移前(WordPress) | 迁移后(Next.js 15) | 改进 |
|---|---|---|---|
| 首次内容绘制(FCP) | 4.2s | 1.1s | -3.1s(快 74%) |
| 最大内容绘制(LCP) | 6.8s | 1.8s | -5.0s(快 74%) |
| 累积布局偏移(CLS) | 0.28 | 0.01 | -0.27(减少 96%) |
| 总阻塞时间(TBT) | 1,200ms | 50ms | -1,150ms(减少 96%) |
| 首字节时间(TTFB) | 2.1s | 0.3s | -1.8s(快 85%) |
| 整体移动端得分 | 35 | 94 | +59 点 |
| 整体桌面端得分 | 61 | 99 | +38 点 |
我想说清楚:这些不是从单个页面精心挑选的数字。我们在 20 个代表性页面上运行了 Lighthouse 并平均了结果。移动端得分在所有测试页面上的范围是 91 到 97。桌面端是 97 到 100。
现在让我为你详细讲解我们如何实现每一项改进。

优化 1:图像优化(LCP -3s)
图像是旧网站上最大的性能杀手。SleepDr 的博客文章包含大量产品摄影和信息图表 —— 通常作为设计师机器上的全分辨率 PNG 直接上传。有些图像有 3-4MB。
我们的做法
对每一个图像使用 next/image。 这个组件做了很多繁重工作:
import Image from 'next/image';
export function HeroImage({ src, alt }) {
return (
<Image
src={src}
alt={alt}
width={1200}
height={630}
priority // 首屏英雄图片:预加载它
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 1200px"
quality={80}
/>
);
}
以下是 next/image 自动处理的内容:
- 格式转换:提供 WebP(或支持的地方提供 AVIF)而不是 PNG/JPEG。仅这一项就使图像大小减少了 60-80%。
- 响应式 srcset:生成多个尺寸,所以移动用户不会下载桌面端大小的图像。
- 默认懒加载:首屏以下的图像在用户滚动到它们附近之前不会加载。
- 明确的尺寸:
width和height属性在布局中预留空间,这直接修复了 CLS。
关键洞察:LCP 元素的优先级加载
英雄图像上的 priority 属性至关重要。没有它,Next.js 会懒加载图像。但如果英雄图像是 LCP 元素 —— 在 SleepDr 的大多数页面上确实是 —— 懒加载它实际上会伤害你的 LCP 得分。你希望它立即开始下载。
我们审计了每个页面模板,识别了 LCP 元素,并用 priority 标记它。博客文章页面使用特色图像。首页使用英雄横幅。简单,但它在 LCP 上产生了 3 秒的差异。
图像 CDN
Vercel 的内置图像优化充当 CDN。图像在首次请求时在边缘处理和缓存。后续访问者在数毫秒内获得缓存的优化版本。不需要 Cloudinary 订阅。不需要 WordPress 插件尝试做相同的事情但更糟。
净影响:仅通过图像优化,LCP 从 6.8s 降到大约 3.8s。其余的 LCP 改进来自 TTFB 改进和字体加载。
优化 2:字体优化(FCP -1.5s)
SleepDr 的 WordPress 主题通过外部样式表链接加载了三个 Google 字体。每一个都是对 fonts.googleapis.com 的渲染阻塞请求,后跟对 fonts.gstatic.com 的另一个请求用于实际字体文件。这是浏览器可以绘制文本前的六个网络往返。
我们的做法
使用 next/font 自托管字体:
import { Inter, Merriweather } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
const merriweather = Merriweather({
weight: ['400', '700'],
subsets: ['latin'],
display: 'swap',
variable: '--font-merriweather',
});
next/font 做得不同的地方:
- 自托管字体文件:没有外部网络请求。字体与构建打包在一起,并从同一 CDN 提供。
- 自动子集化:仅包含你实际需要的字符集。Inter 的拉丁文子集约为 20KB,而不是完整的 100KB+ 文件。
display: 'swap':文本立即使用备用字体呈现,然后在网页字体加载时交换。没有不可见的文本。没有阻塞 FCP 的无样式内容闪现。- CSS 变量注入:字体通过 CSS 自定义属性应用,这意味着当字体交换时零布局偏移,因为我们小心地匹配了备用字体指标。
我们也完全放弃了第三种字体。旧网站使用装饰字体作为标题,这增加了视觉噪音而不是改进可读性。两种字体。就这么多。
净影响:FCP 从消除渲染阻塞字体请求改进了约 1.5 秒。
优化 3:JavaScript 精简(TBT 1200ms → 50ms)
这是单一最大的改进。TBT 为 1,200ms 意味着浏览器的主线程被阻塞了超过一整秒 —— 用户在那段时间内无法点击、滚动或与任何东西交互。
所有那些 JavaScript 从哪里来的?
WordPress 网站加载了:
- jQuery(87KB 压缩) —— 由主题和大多数插件使用
- 34 个插件脚本 —— 联系表单、分析、社交分享、cookie 同意、两个不同的滑块库、灯箱,等等
- 主题 JavaScript —— 另外 150KB 的菜单切换和动画库
- 内联脚本 —— 从各种插件注入到
<head>的随机片段
页面加载时的 JavaScript 总大小:约 1.8MB。在节流移动连接上,解析和执行那需要超过一秒。
我们的做法
零 jQuery. Next.js 使用 React。我们不需要 jQuery。
零插件。 每个功能都被重建为一个目标明确的组件:
- 联系表单:4KB React 组件 + Supabase 服务器操作
- Cookie 同意:2KB 组件带
next/script策略 - 社交分享:原生 Web Share API 带备用链接 —— 不需要库
- 分析:轻量级 Plausible 脚本(< 1KB)
对任何首屏以下的东西进行动态导入:
import dynamic from 'next/dynamic';
const NewsletterSignup = dynamic(
() => import('@/components/NewsletterSignup'),
{ ssr: false } // 仅在客户端加载,仅在需要时
);
const RelatedPosts = dynamic(
() => import('@/components/RelatedPosts')
);
React 服务器组件 处理了大部分渲染。博客文章内容、页眉、页脚、导航 —— 所有都是服务器渲染的,零客户端 JavaScript。只有交互元素(移动菜单切换、联系表单、新闻通讯注册)向浏览器传送 JS。
页面加载时的 JavaScript 总大小迁移后:约 85KB。这是 95% 的减少。
净影响:TBT 从 1,200ms 降到 50ms。 主线程基本上是空闲的。
优化 4:服务端渲染和边缘部署(TTFB -85%)
TTFB 衡量服务器开始发送响应第一字节需要多长时间。SleepDr 的 WordPress 网站在移动端的 TTFB 为 2.1 秒。这意味着在任何东西发生之前 —— 在图像加载之前,在字体下载之前,在 JavaScript 执行之前 —— 用户正在盯着空白屏幕等待服务器响应超过两秒。
WordPress 为什么这么慢
WordPress 上的每个页面请求:
- 访问共享主机服务器(已经很慢)
- 加载 PHP
- 执行 WordPress 核心
- 运行 34 个插件钩子
- 多次查询 MySQL
- 动态生成 HTML
- 发送响应
即使安装了 WP Super Cache,缓存命中率也不一致,服务器本身也不够强大。
我们的做法
对所有 228 篇博客文章进行静态生成。 在构建时,Next.js 将每篇博客文章预渲染为静态 HTML。结果是一组 .html 文件驻留在 Vercel 的边缘网络上 —— 分布在 80 多个全球位置。
当用户请求博客文章时,他们从最近的边缘节点提供的预构建 HTML 文件。没有数据库查询。没有服务端处理。只是从 CDN 读取文件。
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await payload.find({
collection: 'posts',
limit: 300,
});
return posts.docs.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await payload.find({
collection: 'posts',
where: { slug: { equals: params.slug } },
limit: 1,
});
return <ArticleLayout post={post.docs[0]} />;
}
对于联系表单页面,我们使用了服务端渲染,因为它需要动态行为。但即使 Vercel 边缘函数上的 SSR 也在 100ms 内运行,因为计算在边缘发生,而不是在集中式数据中心。
净影响:TTFB 从 2.1s 降到 0.3s —— 85% 的改进。在重复访问和缓存下,它更接近 50ms。
优化 5:第三方脚本管理
第三方脚本是网页性能的无声杀手。SleepDr 的 WordPress 网站加载了 Google Analytics(GA4)、Google Tag Manager、Facebook 像素、Hotjar 录制脚本和 cookie 同意管理器 —— 所有都在 <head> 中渲染阻塞。
我们的做法
Next.js 提供了带有加载策略的 next/script 组件。我们有意使用了它们:
import Script from 'next/script';
{/* 分析:在页面变得可交互后加载 */}
<Script
src="https://plausible.io/js/script.js"
strategy="afterInteractive"
data-domain="sleepdr.com"
/>
{/* Cookie 同意:在浏览器空闲时加载 */}
<Script
src="/scripts/cookie-consent.js"
strategy="lazyOnload"
/>
afterInteractive 策略在 Next.js 水化完成后加载脚本。用户已经可以看到和与页面交互。lazyOnload 策略等待直到浏览器完全空闲 —— 对于非关键脚本很好。
我们也用 Plausible 替换了 Google Analytics(< 1KB,隐私专注,在大多数司法管辖区不需要 cookie 同意)。完全删除了 Hotjar —— SleepDr 实际上并没有查看录制。删除了 Facebook 像素,因为他们六个月前停止运行 Facebook 广告。
杀死不必要的第三方脚本是网页开发中最简单的性能胜利。我一直在说这个。大多数网站加载的脚本来自于团队中没有人在主动使用的服务。
优化 6:CSS 优化(800KB → 35KB)
SleepDr 的 WordPress 主题附带了约 800KB 的 CSS。这包括主题的样式表、插件样式表、完整的 Bootstrap 网格系统(未使用)和 Font Awesome(用于约 12 个图标)。
我们的做法
带有自动清除的 Tailwind CSS。 Tailwind 在构建时扫描你的模板文件,只为你实际使用的实用类生成 CSS。我们的生产 CSS 包:35KB(gzip:~8KB)。
// tailwind.config.ts
export default {
content: [
'./app/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
],
theme: {
extend: {
fontFamily: {
sans: ['var(--font-inter)'],
serif: ['var(--font-merriweather)'],
},
},
},
};
对于 12 个图标,我们使用了内联 SVG。没有图标库。每个 SVG 约为 500 字节。总图标权重:~6KB,而 Font Awesome 的 70KB+。
结果是零渲染阻塞 CSS 请求。Tailwind 的输出由 Next.js 内联到初始 HTML 负载中,所以浏览器可以立即开始渲染。
净影响:CSS 减少了 96%,对 FCP 和 TBT 改进有贡献。
分步检查清单
如果你面临类似的性能问题,这是我要解决事情的确切顺序。这是按影响对努力比率优先的。
第一阶段:快速胜利(第 1 周)
- 在 10 个最高流量页面上运行 Lighthouse(移动端模式)
- 识别每个页面模板上的 LCP 元素
- 为所有图像和 iframe 添加明确的
width和height - 为首屏以下的图像添加
loading="lazy" - 为 LCP 图像添加
fetchpriority="high" - 审计第三方脚本 —— 删除任何未使用的
- 将剩余的第三方脚本移到
async或defer
第二阶段:字体和 CSS(第 2 周)
- 自托管网页字体(消除外部字体请求)
- 为所有
@font-face声明添加font-display: swap - 子集化字体以仅需要的字符集
- 审计 CSS —— 删除未使用的样式表
- 用内联 SVG 替换图标字体
第三阶段:JavaScript(第 3 周)
- 包分析以识别最大的 JS 依赖
- 尽可能删除 jQuery
- 动态导入非关键组件
- 延迟非必需 JavaScript
- 实现每个路由的代码分割
第四阶段:基础设施(第 4 周+)
- 评估 CDN / 边缘部署选项
- 为内容页面实现静态生成
- 设置适当的缓存头
- 如果 WordPress 是瓶颈,考虑完全迁移到现代框架
如果你在考虑最后一点 —— 完全迁移 —— 联系我们。我们已经做过这种类型的项目很多次。我们的 定价页面 有关无头迁移通常成本的详细信息。
2026 年核心网页指标对你的网站意味着什么
谷歌的 2026 年 3 月核心更新改变了游戏规则。CWV 不再按页面评估 —— 它在你的整个域名中汇总,按流量加权。这意味着:
- 被 200 篇博客文章使用的单个缓慢页面模板将使你的整个网站排名下降
- 高流量页面在汇总得分中承载更多权重
- 你不能只优化你的首页并称之为完成
早期的推出数据显示 CWV 不良的网站经历了 20-35% 的有机流量下降。有些下降超过 50%。恢复速度最快的网站是那些在基础设施级别上解决性能的 —— 不是通过调整个别页面,而是通过修复底层架构。
这正是为什么 SleepDr 的迁移如此有效。我们没有优化 228 个单独的 WordPress 页面。我们重建了整个交付系统,所以每一个页面默认都很快。
对于还没有准备好完全迁移的网站,Astro 等框架提供了另一条引人注目的路径 —— 特别是对于你希望默认几乎零 JavaScript 的内容密集型网站。
| 方法 | 典型成本 | 时间 | 预期 Lighthouse 增益 |
|---|---|---|---|
| WordPress 插件优化(WP Rocket、ShortPixel) | $100-500/年 | 1-2 周 | +10-20 点 |
| WordPress 主题替换 | $2,000-5,000 | 2-4 周 | +15-25 点 |
| 无头 CMS 迁移(Next.js/Astro) | $15,000-50,000 | 4-10 周 | +30-60 点 |
| 完全平台重建 | $30,000-100,000+ | 8-20 周 | +40-65 点 |
SleepDr 的项目属于 $20,000-25,000 范围,用于完全迁移,包括所有 228 篇文章的内容转移、CMS 设置、自定义组件和性能优化。Vercel 托管在 Pro 计划上运行 $20/月。这大约是 $740/年,而他们以前为共享托管支付的 $300/年,该托管无法使 TTFB 保持在 2 秒以下。
ROI 如何?他们的有机流量在 6 周内恢复,并在第 10 周超过了前衰退水平。对于依赖有机搜索的业务,迁移在第一季度内为自己付出了代价。
常见问题
核心网页指标的改进需要多久才能影响 Google 排名? 根据我们对 SleepDr 和类似项目的经验,Search Console 在部署后 28 天内开始显示更新的 CWV 数据。排名改进通常在 2-3 个月后随之而来。Google 需要重新爬取你的页面,从真实 Chrome 用户(CrUX 数据)收集新的字段数据,并将其纳入其排名算法中。不要期望一夜之间的结果 —— 但要期望在一个季度内看到可衡量的改进。
Lighthouse 得分 94 对于真实生产网站来说真的可以达到吗? 是的,但它需要从一开始就有意的架构选择。在使用 Next.js 或 Astro 等现代框架时,移动端 90 以上的实验室分数是可以达到的,当你控制第三方脚本、正确优化图像并在边缘网络上部署时。关键是每个组件必须具有性能意识。一个不良的嵌入或未优化的第三方小工具可以将你拉回到 70 多。
我需要从 WordPress 迁移以获得良好的核心网页指标得分吗? 不一定。WordPress 网站可以在正确的主题、积极缓存(WP Rocket + Cloudflare)、优化的托管(Kinsta、WP Engine)和最少的插件下获得良好分数。现实地说,大多数我们审计的 WordPress 网站在移动端的得分在 30-60 之间,因为插件积累和主题开销。如果你在 50 以下,仅靠插件优化可能无法让你超过 75。无头方法 —— WordPress 用作内容 API,而前端框架处理渲染 —— 通常是值得探索的中间地带。
Lighthouse 得分和真实核心网页指标数据之间的区别是什么? Lighthouse 是一个实验室工具 —— 它模拟中端手机在节流 4G 上的表现,并给你合成得分。Search Console 中的核心网页指标是字段数据 —— 来自在 28 天滚动窗口内访问你网站的真实 Chrome 用户的实际测量。Google 使用字段数据作为排名信号,而不是实验室得分。Lighthouse 对于诊断问题和测试修复很有用,但你的目标是在 Search Console 中在第 75 百分位处获得绿色 CWV 状态。
对于 LCP 最有影响的单一优化是什么?
图像优化。在我们审计的大约 60% 的网站中,LCP 元素是一个图像。正确调整它的大小、以 WebP/AVIF 格式提供、添加 fetchpriority="high" 并确保它不会懒加载通常会将 LCP 减少 2-4 秒。在 SleepDr 上,图像优化单独占了大约 3 秒的 LCP 改进。
Google 2026 年整体 CWV 评分如何工作? 自 2026 年 3 月核心更新以来,Google 在你的整个域名中汇总核心网页指标数据,而不是逐页评估页面。高流量页面在计算中承载更多权重。这意味着在数百个页面上使用的缓慢博客存档模板也会拖累你的首页排名。修复是架构性的 —— 你需要每个页面模板都通过 CWV 阈值,而不仅仅是你的关键着陆页。
完整的 WordPress 到 Next.js 迁移通常成本多少? 对于类似 SleepDr 的内容网站(200+ 页面、标准博客布局、联系表单、无电子商务),预期来自经验丰富的机构的 $15,000-30,000。电子商务迁移更高 —— $30,000-75,000+,取决于复杂性。Vercel Pro 上的持续托管是 $20/月。ROI 取决于有机流量对你业务的价值,但对于因 CWV 不良而经历流量下降的网站,迁移通常在 3-6 个月内为自己付出代价。
我应该专注于移动端还是桌面端 Lighthouse 得分? 移动端。总是优先移动端。Google 使用移动优先索引,Lighthouse 移动评分比桌面显著更严厉,因为它模拟受限设备和网络。如果你的移动端得分是 94,你的桌面端得分几乎肯定是 95+。SleepDr 的桌面端得分 99 不需要超出我们为移动端优化所做的任何额外工作。