为什么无头迁移后流量下降,以及如何阻止它
客户端渲染、丢失的 canonical 和一个慢源站。无头迁移静静耗掉自然流量的三种方式——以及如何逐一堵住。
无头 CMS 对你的 HTML 没有任何成见。它通过 API 返回内容;搜索引擎看到的一切,都是由你写的代码产生的。
这就是为什么“无头对 SEO 不好吗?”是个错误的问题。正确的问题是:重建改变了 HTML 的什么? 实际上,答案是三件事之一,而且三件都可以修复。
泄漏 1 —— 只在 JavaScript 运行后才存在的内容
最常见,也最昂贵。
你转向了一个带服务端渲染的框架,然后却在一个客户端 effect 里拉取文章正文,因为教程就是那么写的。于是现在:
- Googlebot 在第一遍得到的是一个空壳,渲染被排队到以后——有时是很久以后。
- 其他爬虫(Bing、AI 爬虫、社交预览机器人)大多根本不渲染。你的链接展开时是空白的。
- Largest Contentful Paint 衡量的是内容,而你的内容在空壳之后一个往返才到达。
诊断 —— 一条命令,无需工具:
0 意味着你的内容不在 HTML 里。在它返回 1 之前,本文其余一切都是次要的。
修复 —— 在服务端拉取。在 Next.js App Router 中这是默认行为;错误通常是一个 'use client' 边界被放在了树中太高的位置。把它下移到那个交互组件上,而不是包住整个页面。
泄漏 2 —— canonical、meta 和结构化数据在重建中丢失
旧 CMS 有一个 SEO 插件,为每个页面生成 canonical 标签、meta 描述、Open Graph 标签和 Article 结构化数据。没有人明确决定要移除它。它只是没在重建清单上。
症状:重复内容聚集(带参数的 URL、尾部斜杠变体、分页归档各自单独被索引)、缺失富结果,以及社交分享展开时标题错误。
修复 —— 让这些字段成为内容模型的一部分,而不是主题的。在 corpusctl 中,SEO 模块把每条条目的标题、描述、canonical 和社交图像与内容一同存储,因此它们随条目一起走,而不是住在渲染它的那东西里。
然后在 CI 中断言它们。一个拉取十个代表性 URL 并检查每个都恰好有一个自指向 canonical、一个不超过 155 字符的非空描述以及有效 JSON-LD 的测试,只花一个小时,却能永久捕获这一类回归。
泄漏 3 —— 一个你没有想过的缓存后面的慢源站
无头通常会让性能更好。当前端在每次请求时都从 CMS 拉取、而 CMS 又隔着一次数据库查询时,它会让性能更差。
你的 TTFB 现在是 CMS 的响应时间加上你的渲染时间,在每一次缓存未命中时都如此,而每一次缓存未命中都是一个真实用户在等待。
修复 —— 决定请求时内容住在哪里。三个选项,按它们经得起考验的程度递增排列:
- 每次请求都拉取。 CMS 处在关键路径上。对仪表盘没问题,对你想要排名的内容则是错的。