JavaScript SEO:为什么 Google 无法看到你的内容
页面在 Chrome 中运行完美,Google 却只索引了空标题和几行页脚文字。工程团队认为现代抓取工具能够执行 JavaScript;SEO 团队却看到 URL 始终没有获得曝光。双方都只说对了一半。
Google 可以渲染 JavaScript,但这不代表每个 JavaScript 应用都能被快速抓取、正确理解和完整索引。应按 Google 实际使用的三个阶段诊断页面:抓取 HTML、渲染 JavaScript,以及索引结果。
Google 如何处理 JavaScript 页面
阶段 1:抓取
Googlebot 获取 URL,读取 HTTP 状态、标头、robots 指令和初始 HTML。它此时已经能提取响应中存在的 <a> 链接、规范链接、标题和内容。
如果服务器返回 404、500、屏蔽抓取,或发送 noindex,处理过程可能在应用运行前停止。
阶段 2:渲染
返回 200 的页面可以进入渲染队列。无界面的 Chromium 版本运行 JavaScript,获取允许访问的资源,并创建渲染后的 DOM。等待时间取决于抓取工具资源。
阶段 3:索引
Google 从渲染后的 HTML 读取内容和链接,然后评估规范链接、质量、重复内容及可索引性。渲染成功仍不保证索引;页面必须提供价值和一致的信号。
最快的测试:禁用 JavaScript
使用“查看源代码”或 curl 检查 HTML 响应。不要只依赖 DevTools 的 Elements,它显示的是脚本运行后的 DOM。
查找以下五项:
- 标题和元描述是否存在?
- H1 和主要文案是否可见?
- 内部路径是否为真实的
<a href>链接? - 规范链接和 robots 标签是否立即正确?
- 服务器是否返回正确状态?
如果响应只包含 <div id="app"></div>,URL 发现便依赖渲染。这并不必然有问题,但会让索引和调试比必要情况更慢。
七种常见的 JavaScript SEO 故障
1. 内容只在用户交互后出现
Googlebot 没有义务点击标签页、展开折叠面板、操作无限滚动或点击“加载更多”。操作后才获取的内容可能永远无法被发现。
将重要内容渲染到 HTML 中,或为每个值得索引的状态提供独立 URL 和可抓取链接。内容已存在于 DOM 中的折叠面板,比点击后才获取内容的方式更稳妥。
2. 客户端路由始终返回 200
SPA 可能显示“未找到”,而服务器返回 200,从而造成软 404。反过来也会发生:有效路由在前端路由器启动前就收到服务器 404。
每个可索引 URL 都需要有意义的服务器状态。缺失页面返回 404;已迁移内容进行重定向;应用临时故障返回 5xx。
3. 链接无法被抓取
这对用户来说看似导航,却不是可靠的抓取路径:
<span onclick="goTo('/products')">Products</span>
应使用:
<a href="/products">Products</a>
只要锚点包含真实 URL,客户端路由器仍可拦截导航。
4. JavaScript 重写规范链接
规范链接应存在于 HTML 源码中并保持稳定。如果源码指向 URL A,脚本却改为 B,抓取工具就会在不同阶段收到冲突信号。同样,不要指望 JavaScript 移除 noindex;Google 可能发现指令后就跳过渲染。
5. Robots 规则屏蔽 bundle 或 API
应用可能需要 JavaScript、CSS 或公开 API 来构建内容。当 Googlebot 无法加载这些资源时,渲染结果可能空白或不完整。
请保护私有 API。使用浏览器网络工具和 Search Console 网址检查来验证公开页面渲染及资源访问;检测到 Cloudflare 并不能验证私有 WAF 策略。
6. 渲染依赖本地存储、Cookie 或位置
Googlebot 像新访客一样访问。如果主要内容只有在存在 localStorage 令牌、特定同意 Cookie 或地理位置结果后才出现,抓取工具可能收到空状态。
提供有用的默认版本。个性化应增强默认内容,而非替换 URL 的整个主题。
7. 水合失败
SSR 可能先发送完整 HTML,随后水合错误删除内容或创建不同的 DOM。搜索引擎或许仍能读取响应,但用户体验和渲染后的链接可能损坏。
监控生产环境的控制台错误、水合不匹配警告和失败请求。影响机器人或较慢设备的故障,很容易在常规 QA 中被遗漏。
CSR、SSR、SSG 和混合渲染
| 渲染模型 | SEO 优势 | 风险 |
|---|---|---|
| CSR | 灵活的前端架构 | 依赖渲染,可能出现空应用外壳 |
| SSR | 内容随 HTML 到达 | 服务器负载和缓存复杂性 |
| SSG | 快速、稳定、便于抓取 | 需要重建策略 |
| Hybrid | 为每个路由匹配渲染方式 | 需要维护更多约定 |
博客、落地页、分类和文档通常能从 SSR 或 SSG 获益。需要登录的仪表盘无需索引,因此使用 CSR 完全合适。
动态渲染曾用于向机器人发送专用 HTML,但维护两个版本会造成内容偏差和成本增加。只要可能,就向用户和抓取工具提供相同的预渲染核心内容。
逐步进行 JavaScript SEO 审核
第 1 步:比较三个版本
将以下内容并排放置:
- HTML 源码;
- 浏览器渲染后的 DOM;
- URL 检查工具中的渲染后 HTML 或截图。
只存在于你的浏览器、却没有出现在 URL 检查工具中的内容,是很有力的线索。
第 2 步:检查请求和资源
寻找返回 403、404、CORS 错误、超时或被 robots 屏蔽的资源。即使主 bundle 正常加载,一个失败 API 也能让整块内容消失。
第 3 步:审核元数据
标题、描述、规范链接、robots 指令和结构化数据都必须对应各自路由。SPA 常会保留前一个路由的元数据,或从未规范化的 URL 派生规范链接。
元标签检查器显示 URL 所提供的标题、规范链接、Open Graph 标签和标题层级。
第 4 步:检查链接和站点地图
内部链接需要 href,站点地图应只包含规范 URL,列出的每个 URL 都必须返回预期状态。站点地图无法弥补不可抓取的导航。
第 5 步:衡量性能
大型 bundle 和长任务会损害用户体验,并提高渲染成本。运行页面速度检查器,重点关注 LCP、INP、TBT 和未使用的 JavaScript。
第 6 步:测试模板,而不只是首页
抽样检查文章、分类、产品、筛选结果、分页和一个不存在的 URL。大多数 JavaScript SEO 缺陷隐藏在开发者很少手动打开的路由中。
一个典型故障
一个招聘网站使用 Vue,在分类组件挂载后获取职位卡片。分类 H1 存在于源码中,但每张职位卡片都由 JavaScript 生成。每张卡片在 <div> 上使用 @click,没有 href。
访客可以正常浏览职位,但 Google 难以找到职位详情,因为站点地图虽列出职位 URL,却缺少可抓取的路径和内部链接;可用 XML 站点地图检查器改善发现过程。
修复办法不是移除 Vue。团队将卡片改为 <a href>,在服务器渲染初始列表,将交互式筛选保留在客户端,并为过期职位返回真正的 404。架构依然现代,而发现过程不再依赖运气。
发布前检查清单
- 核心内容存在于 HTML 中,或能可靠渲染。
- 有效路由返回
200;已移除路由返回404/410。 - 重要导航使用
<a href>。 - 规范链接和 robots 指令存在于源码中并保持稳定。
- 所需 CSS、JavaScript 和 API 可被抓取。
- 新访客空状态不会替代核心内容。
- 导航时元数据正确更新。
- 结构化数据出现在渲染后的 HTML 中。
- 移动端与桌面端提供等效的核心内容。
- URL 检查工具看到的内容与访客相同。
发布后监控 JavaScript SEO
一次性检查能发现明显缺陷,但 JavaScript 应用经常变化。增加一小组生产环境检查,让 SEO 故障在 Search Console 报告趋势前暴露。
对有代表性的公开路由进行 HTML 层面的监控测试:
- 响应中存在预期标题和规范链接;
- 主要标题和可识别的内容片段存在;
- 状态码符合路由状态;
- 至少一个重要内部链接具有真实
href; - robots 指令没有意外变化。
对确实依赖水合的内容,再运行一轮渲染浏览器检查。记录控制台错误、失败网络请求、最终规范链接、结构化数据和截图。HTML 测试保护抓取基础;渲染测试保护实际应用。
按模板选择 URL,不要只按流量选择。首页监控可能一直正常,而产品详情、分页或本地化路由已经损坏。为每种可索引模板保留一个稳定测试样例,并保留一个必须返回 404 的反向测试样例。
发布注释同样有用。索引页面或展示次数下降时,准确知道路由器、同意管理器、渲染框架或 API 何时变化,可以缩短诊断时间。缺少这些历史记录,团队往往会将自己部署引入的回归问题归咎于算法更新。
对大型网站,可自动比较 HTML 源码与渲染后的 DOM。当渲染页面丢失大量文字或链接,或内容仅在延迟的用户动作后才出现时发出告警。这些检查不能替代 URL 检查工具,却能每天发现可预防的错误。
结论
JavaScript 不会导致 SEO 失败。仅在点击后才存在的内容、错误状态码、没有 href 的链接和过晚变化的元数据,才会造成真正损害。让初始响应具有实际内容,确保 URL 和状态真实,然后用 JavaScript 改善体验,而不是隐藏核心内容。
常见问题
Google 能执行 JavaScript 吗?
每个 Vue 或 React 网站都必须全部转为 SSR 吗?
为什么不应由 JavaScript 移除 noindex 标签?
免费检查您的网站
立即运行 SEO 审核或检查您的流量质量——无需注册。