React SEO:SEO 友好的最佳实践

React SEO: SEO 友好的最佳实践

Sam Underwood
Sam Underwood 是一名独立顾问。通过 On-page SEO、技术优化、以及内容策略,帮助电子商务企业增加额外收入。
 React 在现代 Web 开发中的流行趋势中变的越来越重要。

React 和其他类似的程序库(如 Vue.js)逐渐成为需要复杂开发的大型企业的选择,而更简单的方法(如使用 WordPress 主题)将无法满足这些企业的需求。

尽管如此,因为搜索引擎难以有效地渲染 JavaScript,所以 SEO 们最初并没有采用像 React 这样的程序库,而 HTML 源代码中可用的内容是首选。

然而,谷歌和 React 在如何渲染 JavaScript 的发展上已经简化了复杂性,导致 SEO 不再是使用 React 的障碍。

尽管如此仍然存在一些复杂性,我们将在本指南中进行介绍。

关于这一点,我们将介绍以下内容:

React 是由 Meta(前身为 Facebook)开发用于构建 Web 和移动应用程序的开源 JavaScript 程序库,React 的主要特点是它是具有声明性的、基于组件的,并且可以更轻松地操作 DOM

理解组件的最简单方法是将它们视为插件,例如 WordPress。它们允许开发人员使用 MUI 或 Tailwind UI 等组件库快速构建设计并向页面添加功能。

如果你想了解为什么开发人员喜欢 React,请从这里开始:

React 实现了一个 App Shell 模型,这意味着绝大多数内容,默认情况下将是客户端渲染 (CSR)。

而 CSR 意味着 HTML 主要包含 React JS 程序库,而不是从来自服务器(HTML 源)初始的 HTTP 响应中发送整个页面的内容。

它还将包含混杂 JSON 数据的其他 JavaScript 或包含 React 组件的 JS 文件链接,可以通过检查 HTML 源代码快速判断网站是否为客户端渲染。透过点击右键并选择“查看源代码”(或 CTRL + U/CMD + U)。

netlfix.com 主页的 HTML 源代码屏幕截图。

如果在那里看不到很多行 HTML,则该应用程序很可能是客户端渲染。

但是当你通过右键点击并选择“Inspect element”(或 F12/CMD + ⌥ + I)来检查元素时,会看到浏览器生成的 DOM(浏览器在其中渲染了 JavaScript)。

结果是你会看到该网站有很多 HTML:

注意第一个 <div> 上的 appMountPoint ID,通常会在单页应用程序 (SPA)中看到类似的元素,因此像 React 这样的程序库知道应该在哪里注入 HTML。像是 Wappalyzer 这一类的技术检测工具也很擅长检测程序库。

译者注

Ahrefs 的网站诊断将服务器发送的原始 HTML 和浏览器中的渲染 HTML 保存起来,从而更容易发现站点是否具有客户端渲染的内容。

更好的是,可以同时搜索原始 HTML 和渲染 HTML,用以了解具体在客户端渲染的内容。在下面的例子中,你可以看到这个网站是在客户端渲染的页面关键内容,比如 <h1> 标签。

Joshua Hardwick
Joshua Hardwick
内容主管

使用 React 创建的网站更不同于传统的方法:也就是使用像是 PHP 之类的语言将繁重的渲染内容留在服务器上,也称之为服务器端渲染 (SSR)。

上面显示了服务器使用 React 将 JavaScript 渲染成 HTML(稍后会详细介绍),对于使用 PHP 构建的网站(像是 WordPress),这个概念是相同的,只是 PHP 变成了 HTML 而不是 JavaScript。

在 SSR 之前,开发人员让它变得更加简单。

他们会创建静态的 HTML 文档,将它们托管在服务器上,然后立即发送。服务器不需要渲染任何东西,而浏览器通常很少进行渲染。

SPA(包括那些使用 React 的)现在正全面回到这种静态方法,他们现在在浏览器请求 URL 之前将 JavaScript 预渲染为 HTML。这种方法称为静态站点生成 (SSG),也称为静态渲染。

在实践中,SSR 和 SSG 是相似的。

主要区别在于,当浏览器请求 URL 时使用 SSR 进行渲染,而在构建时使用 SSG(当开发人员部署新代码或网站管理员更改站点内容时)使用框架预渲染内容。

由于服务器在将内容发送到用户浏览器呈现内容之前,存在额外的延迟,SSR 可以更加动态但会更慢。

因为内容已经被渲染所以 SSG 会更快,这意味着它可以立即提供给用户页面内容(也就意味着更快的 TTFB)。

要了解 React 默认的客户端渲染方法为何会导致 SEO 的问题,首先需要了解 Google 如何抓取、处理和索引页面。

我们可以通过以下步骤总结其工作原理:

  1. 爬取 – Googlebot 针对抓取队列中的网址向服务器发送 GET 请求并保存响应内容,Googlebot 为 HTML、JS、CSS、图像文件等执行此操作。
  2. 处理 – 这包含将从 HTML 内的 <a href> 找到的链接 URL 添加到爬网队列中,它还包括在 <link> 标记中找到的排队资源 URL (CSS/JS) 或 <img src> 标记中的图像。如果 Googlebot 在这个阶段发现了一个 noindex 标签,这个过程就会停止,Googlebot 不会渲染内容,Caffeine(谷歌的索引器)也不会索引它。
  3. 渲染 – Googlebot 使用无头 Chromium 浏览器执行 JavaScript 代码,以查找 DOM 中的其他内容,而不是 HTML 源代码,它对所有 HTML URL 执行此操作。
  4. 索引 – Caffeine 从 Googlebot 获取信息,对其进行规范化(修复损坏的 HTML)然后尝试理解,预先计算一些排名信号,以便在搜索结果中提供排名。

小提示.
 如果想了解有关此过程的更多信息,Google 有很详细的解释。Patrick Stox 也有一篇文章解释了 JavaScript SEO 需要了解的关键信息

从历史上看,React 和其他 JS 库的问题是因为 Google 没有很好地处理渲染过程。

一些例子包括:

值得庆幸的是,谷歌现在已经解决了大部分这些问题。Googlebot 现在是常青状态,这意味着它始终支持 Chromium 的最新功能。

此外现在的渲染延迟为 5 秒,正如 Martin Splitt 在 2019 年 11 月的 Chrome 开发者峰会上宣布的那样:

去年 Tom Greenaway 和我在这个舞台上告诉你,“嗯,你知道,这可能需要一周的时间,我们对此感到非常抱歉。”现在把这个忘记好吗? 因为新的数字看起来好多了。我们实际上检查了这些数字并发现,我们从爬行到实际呈现这些结果之间所花费的时间是在中位数上,是 5 秒!”

这一切听起来都是正向的,但是客户端渲染并让 Googlebot 呈现内容是正确的策略吗?

答案很可能仍然是否定的。

在过去的五年中,谷歌在处理 JavaScript 内容方面进行了创新,但完全由客户端渲染的网站引出了其它需要考虑的问题。

重要的是,你可以克服 React 和 SEO 的所有问题

React JS 是一个开发工具,React 与开发堆栈中的其他工具并没有什么不同,无论是 WordPress 插件还是你选择的 CDN,如何配置会决定是否会降低/增强 SEO。

归根结底 React 还是有利于 SEO,因为它改善了用户体验,只需要确保考虑以下常见问题。

1. 选择正确的渲染策略

你需要用 React 解决最重要的问题是它如何渲染内容。

如前所述,Google 现在擅长渲染 JavaScript。但不幸的是其他搜索引擎并非如此,Bing 对 JavaScript 渲染有一些支持,不过它的渲染效率仍未知,百度、Yandex 等其他搜索引擎也仅提供有限的支持。

小提示.
此限制不仅会影响搜索引擎,除了站点审核员之外,抓取网页并提供像是站点反向链接等元素的关键数据 SEO 工具并不会渲染 JavaScript。这会对他们提供的数据质量产生重大影响,唯一的例外是 Ahrefs,它自 2017 年以来一直在网页上渲染 JavaScript,目前每天渲染超过 2 亿个页面

提出这个未知数,能为解决服务器端渲染提供了一个很好的案例,以确保所有爬虫都能看到网站的内容。

此外,在服务器上呈现内容还有另一个重要的好处:加载时间

加载时间

渲染 JavaScript 占用大量 CPU;这使得像 React 这样的大型程序库加载速度更慢,并对用户来说更具交互性。对于 SPA,尤其是在移动设备这种用户查看页面的主要方式上,通常会看到 Core Web Vitals(例如交互时间 (TTI))要高得多。

一个利用客户端渲染的 React 应用程序范例。

但是在浏览器进行初始渲染后,随后的加载时间往往会更快,原因如下:

根据每次访问查看的页面数,这可能导致实际数据总体上是正向的。

但是如果网站每次访问浏览的页面数量很少,你就很难获得所有核心网页指标(Core Web Vitals)的正向实际数据。

解决方案

最好的方式就是选择 SSR 或 SSG,主要是因为:

  • 更快的初始渲染。
  • 不必依赖搜索引擎爬虫来渲染内容。
  • 由于浏览器在交互之前解析和渲染的 JavaScript 代码更少,TTI 得到了改进。

透过 ReactDOMServer 可以在 React 中实现 SSR,但是我建议使用 Next.js 的 React 框架并使用其 SSG 和 SSR 选项。你也可以使用 Next.js 实现 CSR,但由于速度关系,该框架让用户更倾向 SSR/SSG。

Next.js 支持它所谓的“自动静态优化”,实际上这意味着可以在站点上拥有一些使用 SSR 的页面(例如帐户页面)和使用 SSG 的其他页面(例如你的博客)。

呈现结果:非动态页面的 SSG 和快速 TTFB,以及 SSR 作为动态内容备份的渲染策略。

小提示.
你可能听说过 React Hydration with ReactDOM.hydrate(),这是一个透过 SSG/SSR 交付内容,然后在初始渲染期间变成客户端渲染应用程序的地方。在未来的动态应用上,这可能是比 SSR 更好的选择。然而混合使用在目前的运作方式就是加载整个 React 程序库,然后将事件处理程序附加到即将发生变化的 HTML。然后 React 使浏览器和服务器之间的 HTML 保持同步。目前我还不推荐这种方法,因为它对于初始渲染的 TTI 等 Web Vitals 仍然有负面影响。部分混合使用可能会在未来通过仅混合页面的关键部分(例如浏览器可视区的部分)而不是整个页面,以此解决问题;在那之前 SSR/SSG 是更好的选择。

既然我们在谈论速度,我如果不提其他优化方式反而是在帮倒忙。Next.js 优化了 React 应用程序的关键渲染路径,具有以下功能:

  • 图像优化 – 这增加了 <img> 的宽度和高度属性、srcset、延迟加载和图像大小调整。
  • 字体优化 – 这内联了关键字体 CSS 并添加了字体显示控制。
  • Script 优化 – 这使你可以选择何时加载脚本:在页面交互或懒加载之前/之后。
  • 动态导入 – 如果实施代码拆分的最佳实践,此功能可以在需要时更轻松地导入 JS 代码,而不是让它在初始渲染时加载并减慢它的速度。

速度和正向的 Core Web Vitals 是一个排名因素,尽管是次要因素。Next.js 的功能可以更轻松地创建出色的网页体验,从而带来竞争优势。

提示

许多开发人员使用 Vercel(Next.js 的创建者)部署他们的 Next.js Web 应用程序,它拥有全球边缘服务器网络;这使得加载时间更快速。

Vercel 提供有关平台上部署的所有站点的 Core Web Vitals 的数据,但你也可以使用 Ahrefs 的网站诊断获取每个 URL 的详细网页体验核心指标数据。

只需在项目的爬网设置中添加 API 密钥。

运行审核后,前往查看性能区域。在那里 Ahrefs 的网站诊断将展示显示来自 Chrome 用户体验报告 (CrUX) 和 Lighthouse 的数据的图表。

2. 正确使用状态码

大多数 SPA 的一个常见问题是它们没有正确呈现状态代码,因为服务器没有加载页面,而浏览器有。你通常会看到以下问题:

  • 没有 3xx 重定向,而是使用 JavaScript 重定向。
  • 4xx 状态代码未报告“未找到”URL。

你可以在下面看到我使用 httpstatus.io 在 React 站点上运行了一个测试,该页面显然应该是 404,但它却返回 200 状态码,这称为软 404。

这里的风险是谷歌可能决定索引该页面(取决于其内容),然后 Google 可以将其提供给用户,或者在评估网站时使用。

此外呈现 404 有助于 SEO 审核网站,如果不小心在内部链接到 404 页面并返回 200 状态代码,那么使用审核工具快速发现该问题可能会变得更困难。

有几种方法可以解决这个问题,如果是客户端渲染:

  1. 使用 React 路由器框架
  2. 创建一个 404 组件,在无法识别路线时显示。
  3. 将 noindex 标签添加到“未找到”页面。
  4. 将带有“404:找不到页面”之类的消息使用 <h1>,这并不理想,因为我们沒有报告 404 状态码。但它会阻止谷歌将该页面编入索引,并帮助它将该页面识别为软 404。
  5. 当需要更改 URL 时使用 JavaScript 重定向。同样的這并不理想,但 Google 确实遵循 JavaScript 重定向并传递排名信号。

如果使用 SSR,Next.js 使用狀態响应帮助器會使这变得简单,它允许你设置所需的任何状态代码,包括 3xx 重定向或 4xx 状态代码。我使用 React Router 概述的方法也可以在使用 Next.js 时使用,但是如果你使用的是 Next.js,那么可能还能夠实现 SSR/SSG。

3. 避免杂凑(hash)URLs

这个问题在 React 中并不常见,但必须避免像下面这样的杂凑 URL:

  • https://reactspa.com/#/shop
  • https://reactspa.com/#/about
  • https://reactspa.com/#/contact

一般来说,谷歌在杂凑之后不会看到任何东西,所有这些页面都会被视为 https://reactspa.com/。

解决方案

带有客户端路由的 SPA 应该布署 History API 来更改页面。

你可以使用 React Router 和 Next.js 能更容易地做到这一点。

4. 在相关的地方使用 <a href> 链接

SPA 的一个常见错误是使用 <div> 或 <button> 来更改 URL,这不是 React 本身的问题,而是程序库的使用方式。

这样做会给搜索引擎带来问题,如前所述当 Google 处理 URL 时,它会在 <a href> 元素中查找要抓取的其他 URL。

如果缺少 <a href> 元素,Google 将不会抓取 URL 也不会传递 PageRank

解决方案

解决方案是 <a href> 的 URLs 链接到你希望 Google 发现的页面。

检查是否正确链接到 URL 很容易,只要检查内部链接的元素并检查 HTML 以确保已包含 <a href> 链接。

如上例所示,如果不是的话可能会遇到问题。

但重要的是,要了解缺少 <a href> 链接并不总是问题,CSR 的一个好处是,当内容对用户有帮助但对搜索引擎没有帮助时,可以在客户端更改内容并且不包含 <a href> 链接

在上面的示例中,网站使用分面导航链接到数百万个过滤器组合,这些过滤器对搜索引擎抓取或索引并没有用处。

在客户端加载这些筛选器是很有意义的一件事,因为该网站可以透过不添加 <a href> 链结让 Google 来节省抓取预算

Next.js 通过其链结组件使这变得简单,可以将其配置为允许客户端导航

如果你决定布署一个完整的 CSR 应用程序,可以使用使用 React Router 的 onClick 和 History API 更改 URL。

5. 避免延迟加载必要的 HTML

当用户点击或悬停在一个元素上时,很常见到使用 React 开发的网站将内容注入 DOM(仅因为使用程序库很容易做到)。

这本身并不坏,但是以这种方式添加到 DOM 的内容是不会被搜索引擎看到,如果注入的内容包括重要的文本内容或内部链接,这可能就会有负面影响:

  • 页面表现如何(因为 Google 不会看到内容)。
  • 其他 URL 是否能被发现(因为 Google 不会找到内部链接)。

这是我最近审核 React JS 网站上的一个示例,这里我将展示一个著名的电子商务品牌,其分面导航中具有重要的内部链接。

但是当你点击“筛选器”按钮时,会在 DOM 中注入一个显示移动设备导航的模式,查看下面 HTML 中的第二个 <!—-> 可以看到:

解决方案

发现这些问题并不容易,据我所知没有工具会直接告诉你。

相反的,它需要透过检查常见元素来查看,例如:

  • 选项卡
  • 模式
  • 页签
  • 下拉菜单
  • 汉堡菜单

然后需要检查它们上的元素,并在通过点击或悬停来打开/关闭它们时观察 HTML 发生的情况(就像我在上面的 GIF 中所做的那样)。

假设你注意到 JavaScript 正在向页面添加 HTML,这种情况下需要与开发人员合作。如此一来,不是透过内容注入 DOM 的方式,而是默认包含在 HTML 中,并通过 CSS 使用 visibility: hidden; 或是 display: none; 来显示或隐藏内容。

6.不要忘记基本面

虽然 React 应用程序还有其他 SEO 的考虑因素,但这并不意味着其他基础知识不适用。

仍然需要确保你的 React 应用程序遵循以下最佳实践:

最后的想法

不幸的是使用 React 应用程序,增加了原本技术 SEO 就需要检查的一份很长的问题清单。但是多亏了像 Next.js 这样的框架,它使 SEO 的工作比以往更加简单。

希望本指南能帮助你更好地了解作为 SEO 使用 React 应用程序时需要考虑的其他注意事项。

对使用 React 有任何疑问吗?来 twitter 上找我

译者,李元魁,SEO 分解茶博客创始人