React SEO:SEO 友好的最佳实践

React SEO: SEO 友好的最佳实践

Sam Underwood
Sam Underwood 是一名独立顾问。通过 On-page SEO、技术优化、以及内容策略,帮助电子商务企业增加额外收入。
Article Performance
Data from Ahrefs
  • 链接网站

The number of websites linking to this post.

This post's estimated monthly organic search traffic.

 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 分解茶博客创始人

Article Performance
Data from Ahrefs
  • 链接网站

The number of websites linking to this post.

This post's estimated monthly organic search traffic.