技术 SEO · 第 11 篇

JavaScript SEO 基础:渲染、可索引内容与懒加载

约 16 分钟阅读 更新于 2026-06-24 MagicSEO 编辑部 · 人工审核 渲染与索引

现代网站越来越依赖 JavaScript 来渲染内容。问题是:搜索引擎能不能"看到"这些靠 JS 生成的内容?答案是"能,但有代价、有延迟、有不确定性"。理解 Google 的渲染机制,避开客户端渲染的常见陷阱,让关键内容稳定可索引,是每个用框架建站的人都该掌握的技术 SEO 基本功。

Google 的两阶段渲染#

Google 处理网页不是一步完成,而是分两个阶段(常被称为"两波索引")。这一机制在抓取与收录原理中已简述,这里展开:

  1. 第一阶段:抓取与初始 HTML 解析。Googlebot 抓取 URL,解析返回的原始 HTML,提取其中的文本、链接,并把页面排入渲染队列。这一步几乎实时。
  2. 第二阶段:渲染。Google 的网页渲染服务(WRS)用一个无头 Chromium 浏览器执行页面的 JavaScript,生成最终的 DOM。只有这一步完成后,JS 注入的内容才进入索引。
渲染延迟是核心风险两个阶段之间存在时间差。第一阶段实时完成,但渲染要排队等待 WRS 资源,延迟可能从几小时到几周。如果你的内容只在第二阶段(JS 执行后)才出现,它的发现和收录就会被这段延迟拖住——而初始 HTML 里就有的内容则无此问题。

三种渲染模式#

同一个页面,内容在什么时候、什么地方被"渲染"成 HTML,决定了它对 SEO 的友好程度。

模式内容在哪生成初始 HTMLSEO 友好度
CSR 客户端渲染用户浏览器执行 JS空壳(只有容器)⚠️ 依赖渲染,有延迟风险
SSR 服务端渲染服务器每次请求时生成完整内容✅ 友好
SSG 静态生成构建时预先生成完整内容✅ 最友好(兼顾速度)

CSR:客户端渲染

纯 CSR 的页面,初始 HTML 往往只是这样一个空壳:

纯 CSR 的初始 HTML
<body>
  <div id="root"></div>   <!-- 空的,内容全靠 JS 注入 -->
  <script src="/app.js"></script>
</body>

搜索引擎第一波只看到一个空 <div>,必须等到渲染阶段执行完 app.js 才能看到真实内容。这就是单页应用(SPA)SEO 困难的根源。

SSR:服务端渲染

SSR 在服务器上为每个请求执行框架代码,返回已经填好内容的完整 HTML,浏览器拿到后再"激活"(hydration)接管交互。搜索引擎第一波就能看到全部内容。代价是服务器需要为每次请求做渲染,有运行时开销。

SSG:静态生成

SSG 在构建时就把所有页面渲染成完整的 HTML 文件,部署后就是一堆静态文件,无需服务端运行时。它同时具备 SEO 友好(内容在 HTML 中)、速度极快(可走 CDN)、成本低、攻击面小等优点,是内容型网站的理想选择。

如何选内容为主、更新不频繁(博客、文档、营销站)→ 优先 SSG。内容高度动态、因用户/请求而变(仪表盘、个性化页)→ SSR。纯交互应用且对 SEO 无要求(后台工具)→ CSR 也无妨。很多框架(Next.js、Nuxt、Astro)支持按页面混合使用这几种模式。

让内容可被索引#

无论用什么框架,核心原则只有一条:关键内容应当在初始 HTML 中就存在,或确保能被可靠渲染。具体注意:

  • 关键文本不要只靠 JS 注入:标题、正文、产品信息等核心内容尽量服务端输出。
  • meta 标签要在 HTML 中titledescription、canonical、hreflang、结构化数据等最好在初始 HTML 里,靠 JS 动态写入虽可被读取,但增加不确定性。
  • 不要因 User-Agent 区别对待:给搜索引擎和用户返回不同内容属于伪装(cloaking),违反规范。
  • 避免渲染依赖用户交互:需要点击、滚动才加载的内容,爬虫可能看不到。

链接是搜索引擎发现页面的主要途径。JavaScript 站点最常见的错误是用脚本事件模拟"链接",导致爬虫无法跟踪。

链接的正确与错误写法
<!-- 好:真实的 a 标签 + href,爬虫能跟踪 -->
<a href="/articles/zh/technical-seo/javascript-seo.html">JS SEO</a>

<!-- 差:onclick 跳转,没有 href,爬虫无法发现目标 -->
<span onclick="location.href='/page'">点击</span>

<!-- 差:用按钮做导航 -->
<button onclick="goTo('/page')">下一页</button>

规则很简单:导航必须使用带 href 的真实 <a> 标签,指向真实 URL。前端路由(如 React Router)也应基于 <a href> 实现,让 JS 拦截点击做无刷新跳转的同时,保留可被抓取的 href。这一点与URL 结构移动端导航的要求一致。

懒加载的正确姿势#

懒加载能显著提升加载速度,但实现不当会让内容对爬虫不可见。关键区别在于"加载触发方式":

做法对 SEO
图片用原生 loading="lazy"✅ 安全,浏览器与爬虫都能正确处理
用 IntersectionObserver 懒加载,且内容有真实链接/在 DOM 中✅ 基本安全
必须用户滚动才加载下一批内容(无分页链接)⚠️ 爬虫不滚动,可能看不到
"加载更多"按钮且无对应可抓取 URL⚠️ 后续内容难被发现
无限滚动要配真实分页Googlebot 不会像真人那样滚动页面去触发加载。如果用无限滚动展示列表,务必同时提供可抓取的分页 URL(如 ?page=2 且每页有真实链接),让爬虫能逐页发现内容。这部分在「分页、筛选与参数 URL」一篇会专门展开。

常见陷阱#

  • robots.txt 屏蔽了 JS/CSS:渲染需要这些资源,屏蔽后 Google 无法正确渲染页面(见 robots.txt 配置)。
  • 关键内容依赖客户端请求:内容靠 JS 发起 API 请求后才填充,渲染失败或超时就什么都没有。
  • 用 # 片段做路由example.com/#/page 这类哈希路由对收录不友好,应使用 History API 的真实路径。
  • meta/canonical 被 JS 覆盖出错:动态写入时逻辑出 bug,可能给所有页面写上相同或错误的 canonical。
  • JS 错误中断渲染:一个未捕获的脚本异常可能让整页内容无法生成。
  • 渲染超时:脚本过重、请求过慢,渲染在完成前被中断,内容缺失。

如何排查#

判断"搜索引擎到底看到了什么",用这些方法:

  • GSC URL 检查工具:查看 Google 渲染后的 HTML 和截图,确认 JS 内容是否被看到——这是最权威的方式。
  • 富媒体结果测试 / 移动设备适合性测试:也能查看 Google 渲染后的结果。
  • 查看渲染后源码:浏览器里"查看网页源代码"看到的是初始 HTML;开发者工具 Elements 面板看到的是渲染后 DOM。对比两者,能直观看出哪些内容是 JS 注入的。
  • 禁用 JavaScript 访问:在浏览器中关闭 JS 再打开页面,看还剩多少内容——剩下的就是初始 HTML 里的部分。

更多细节参见 Google 官方文档:JavaScript SEO 基础知识

本站为什么用纯静态#

本站示范MagicSEO 刻意采用纯静态 HTML(相当于最彻底的 SSG):每篇文章的全部正文、标题、链接、meta 和结构化数据都写在初始 HTML 中,不依赖任何客户端框架渲染内容。Googlebot 在第一波抓取时就能拿到完整内容,完全跳过渲染队列和延迟。页面上仅有的 JS(主题切换、轻量动效)都是渐进增强——即使禁用 JavaScript,所有内容和导航链接依然完整可用。这正是本文主张的"关键内容在初始 HTML 中"的极致实践。

JavaScript SEO 清单#

  • 关键内容在初始 HTML 中可见(SSR/SSG 或静态)
  • title/description/canonical/结构化数据在 HTML 中
  • 导航使用带 href 的真实 a 标签
  • 前端路由使用 History API 真实路径,非 # 哈希
  • robots.txt 未屏蔽渲染所需的 JS/CSS
  • 图片用原生 loading="lazy"
  • 无限滚动配套可抓取的分页 URL
  • 关键内容不依赖用户点击/滚动才出现
  • 不对搜索引擎与用户返回不同内容(无 cloaking)
  • 用 GSC URL 检查确认渲染后内容完整

常见问题#

Google 能抓取 JavaScript 生成的内容吗?

能,但有代价。Google 会用无头 Chromium 执行 JavaScript 来渲染页面,所以客户端渲染的内容理论上可以被索引。但渲染需要排队、消耗资源,存在从几小时到几周不等的延迟,而且并非每个搜索引擎、每次抓取都能完整渲染。依赖 JavaScript 才能显示的关键内容,发现和收录都会被推迟,存在不确定性。最稳妥的做法是让核心内容在初始 HTML 中就存在。

单页应用(SPA)对 SEO 不友好吗?

纯客户端渲染的 SPA 对 SEO 有天然劣势:初始 HTML 往往只有一个空容器,内容全靠 JS 注入,搜索引擎需要额外渲染才能看到,且渲染有延迟和不确定性。解决办法不是放弃 SPA,而是给它加上服务端渲染(SSR)或预渲染/静态生成(SSG),让首屏关键内容直接出现在 HTML 中,同时保留客户端交互能力。Next.js、Nuxt 等框架就是为此设计的。

SSR、SSG 和 CSR 有什么区别?

CSR(客户端渲染)由浏览器执行 JS 生成内容,初始 HTML 是空壳;SSR(服务端渲染)在服务器为每次请求生成完整 HTML 再交给浏览器;SSG(静态生成)在构建时就生成好所有页面的完整 HTML,部署为静态文件。从 SEO 角度,SSG 和 SSR 都让内容在初始 HTML 中可见,对搜索引擎最友好;SSG 还兼具最快的速度和最低的服务器成本,适合内容型网站。

懒加载会影响 SEO 吗?

正确实现的懒加载不影响 SEO,还能提升加载速度。但如果用纯 JavaScript 的滚动懒加载(必须用户滚动或交互才加载内容),Googlebot 不会像真人那样滚动,可能看不到这些内容。安全做法是:图片用原生 loading="lazy";列表内容确保有可被抓取的真实链接或在 HTML 中可访问,不要让关键内容只在用户交互后才出现。