React SEO 策略和最佳实践

已发表: 2022-03-11

开发 React 是为了创建声明性模块化跨平台的交互式 UI。 今天,它是用于编写高性能前端应用程序的更流行(如果不是最流行)的 JavaScript 框架之一。 React 最初开发用于编写单页应用程序 (SPA),现在用于创建成熟的网站和移动应用程序。

如果您在传统 Web 开发方面拥有丰富的经验并迁移到 React,您会注意到越来越多的 HTML 和 CSS 代码迁移到 JavaScript。 这是因为 React 不建议直接创建或更新 UI 元素,而是描述 UI 的“状态”。 React 然后会更新 DOM 以最有效的方式匹配状态。

因此,对 UI 或 DOM 的所有更改都必须通过 React 的引擎进行。 尽管对开发人员来说很方便,但这可能意味着用户的加载时间更长,搜索引擎需要更多的工作来查找和索引内容。

在本文中,我们将解决在构建具有 SEO 性能的 React 应用程序和网站时面临的挑战,我们将概述用于克服这些挑战的几种策略。

Google 如何抓取和索引网页

谷歌接收了超过 90% 的在线搜索。 让我们仔细看看它的爬取和索引过程。

这张取自 Google 文档的快照可以帮助我们。 请注意,这是一个简化的框图。 实际的 Googlebot 要复杂得多。

Googlebot 索引网站的图表。

注意事项:

  1. Googlebot 会维护一个抓取队列,其中包含它需要在未来抓取和编入索引的所有网址。
  2. 当爬虫空闲时,它会拾取队列中的下一个 URL,发出请求并获取 HTML。
  3. 解析 HTML 后,Googlebot 确定是否需要获取并执行 JavaScript 来呈现内容。 如果是,则将 URL 添加到呈现队列中。
  4. 稍后,渲染器获取并执行 JavaScript 以渲染页面。 它将呈现的 HTML 发送回处理单元。
  5. 处理单元提取网页上提到的所有 URLs <a> tags ,并将它们添加回抓取队列。
  6. 内容被添加到 Google 的索引中。

请注意,解析 HTML 的处理阶段和执行 JavaScript 的渲染器阶段之间有明显的区别。

之所以存在这种区别,是因为执行 JavaScript 的成本很高,因为 Googlebot 需要查看超过 130 万亿个网页。 因此,当 Googlebot 抓取网页时,它会立即解析 HTML,然后将 JavaScript排队等待稍后运行。 谷歌的文档提到页面会在渲染队列中停留几秒钟,尽管它可能会更长。

还值得一提的是抓取预算的概念。 Google 的抓取受限于 Googlebot 实例的带宽、时间和可用性。 它分配特定的预算或资源来索引每个网站。 如果您正在构建一个包含数千个页面的内容较多的大型网站(例如,电子商务网站),并且这些页面使用大量 JavaScript 来呈现内容,那么 Google 可能能够从您的网站中读取更少的内容。

注意:您可以在此处阅读 Google 管理抓取预算的指南。

为什么为 SEO 优化 React 具有挑战性

我们对 Googlebot、抓取和索引编制的简要概述仅涉及表面。 然而,软件工程师应该识别搜索引擎在尝试爬取和索引 React 页面时面临的潜在问题。 现在我们可以仔细看看是什么让 React SEO 具有挑战性,以及开发人员可以做些什么来解决和克服其中的一些挑战。

空的首过内容

我们知道 React 应用程序严重依赖 JavaScript,而且它们经常遇到搜索引擎的问题。 这是因为 React 默认使用应用程序外壳模型。 初始 HTML 不包含任何有意义的内容,用户或机器人必须执行 JavaScript 才能看到页面的实际内容。

这种方法意味着 Googlebot 在第一遍检测到一个空白页面。 只有在呈现页面时,Google 才能看到内容。 在处理数千个页面时,这将延迟内容的索引。

加载时间和用户体验

获取、解析和执行 JavaScript 需要时间。 此外,JavaScript 可能需要进行网络调用来获取内容,并且用户可能需要等待一段时间才能查看请求的信息。

谷歌已经列出了一组与用户体验相关的网络生命力,用于其排名标准。 较长的加载时间可能会影响用户体验得分,从而促使 Google 将网站排名较低。

我们将在下一节中详细审查网站性能。

页面元数据

<meta>标签很有帮助,因为它们允许 Google 和其他社交媒体网站显示适当的标题、缩略图和页面描述。 但是这些网站依赖于获取的网页的<head>标签来获取这些信息。 这些网站不会为目标页面执行 JavaScript。

React 在客户端呈现所有内容,包括元标记。 由于整个网站/应用程序的应用程序外壳是相同的,因此可能很难为各个页面调整元数据。

网站地图

站点地图是一个文件,您可以在其中提供有关您站点上的页面、视频和其他文件以及它们之间的关系的信息。 像 Google 这样的搜索引擎会读取此文件以更智能地抓取您的网站。

React 没有内置的方式来生成站点地图。 如果你使用 React Router 之类的东西来处理路由,你可以找到可以生成站点地图的工具,尽管这可能需要一些努力。

其他 SEO 考虑因素

这些注意事项通常与建立良好的 SEO 实践有关。

  1. 拥有一个最佳的 URL 结构,让人类和搜索引擎对页面上的期望有一个很好的了解。
  2. 优化 robots.txt 文件可以帮助搜索机器人了解如何抓取您网站上的页面。
  3. 使用 CDN 提供所有静态资产,如 CSS、JS、字体等,并使用响应式图像来减少加载时间。

我们可以通过使用服务器端渲染 (SSR) 或预渲染来解决上面列出的许多问题。 我们将在下面回顾这些方法。

输入同构反应

同构的字典定义是“形式上对应或相似”。

在 React 术语中,这意味着服务器具有与客户端类似的形式。 换句话说,您可以在服务器和客户端上重用相同的 React 组件。

这种同构方法使服务器能够渲染 React 应用程序并将渲染的版本发送给我们的用户和搜索引擎,以便他们可以在 JavaScript 在后台加载和执行时立即查看内容。

Next.js 或 Gatsby 等框架已经普及了这种方法。 我们应该注意到,同构组件看起来可能与传统的 React 组件有很大不同。 例如,它们可以包含在服务器而不是客户端上运行的代码。 它们甚至可以包含 API 机密(尽管服务器代码在发送到客户端之前已被剥离)。

需要注意的一点是,这些框架抽象了很多复杂性,但也引入了一种固执己见的代码编写方式。 我们将在本文中进一步探讨性能权衡。

我们还将进行矩阵分析,以了解渲染路径与网站性能之间的关系。 但在此之前,让我们了解一些衡量网站性能的基础知识。

网站性能指标

让我们来看看搜索引擎用来对网站进行排名的一些因素。

除了快速准确地回答用户的查询外,谷歌认为一个好的网站应该具备以下属性:

  • 它应该快速加载。
  • 用户应该能够在没有太多等待时间的情况下访问内容。
  • 它应该尽早与用户的操作交互。
  • 它不应获取不必要的数据或执行昂贵的代码以防止耗尽用户的数据或电池。

这些特征大致映射到以下指标:

  • TTFB : Time to First Byte – 点击链接和第一个内容进入之间的时间。
  • LCP : Largest Contentful Paint – 请求的文章变得可见的时间。 Google 建议将此值保持在 2.5 秒以下。
  • TTI :交互时间——页面变为交互的时间(用户可以滚动、点击等)。
  • Bundle size – 在页面完全可见和交互之前下载和执行的代码的总字节数。

我们将重新审视这些指标,以更好地了解各种渲染路径如何影响它们中的每一个。

接下来,让我们了解 React 开发人员可用的不同渲染路径。

渲染路径

我们可以在浏览器或服务器上渲染一个 React 应用程序并产生不同的输出。

客户端和服务器端渲染应用程序之间的两个功能发生了显着变化,即路由代码拆分。 我们在下面仔细看看这些。

客户端渲染 (CSR)

客户端渲染是 React SPA 的默认渲染路径。 服务器将提供一个不包含任何内容的shell 应用程序。 一旦浏览器下载、解析和执行包含的 JavaScript 源代码,就会填充或呈现HTML 内容。

路由功能由客户端应用程序通过管理浏览器历史记录来处理。 这意味着无论请求哪个路由,都会提供相同的 HTML 文件,并且客户端会在呈现后更新其视图状态。

代码拆分相对简单。 您可以使用动态导入或 React.lazy 拆分代码,以便仅根据路由或用户操作加载所需的依赖项。

如果页面需要从服务器获取数据来呈现内容——例如,博客标题或产品描述——它只能在相关组件被安装和呈现时这样做。

当网站获取其他数据时,用户很可能会看到“加载数据”标志或指示符。

使用引导数据 (CSRB) 进行客户端渲染

考虑与 CSR 相同的场景,但不是在呈现 DOM 后获取数据,假设服务器发送的相关数据在提供的 HTML 中引导。

我们可以包含一个看起来像这样的节点:

 <script type="application/json"> {"title": "My blog title", "comments":["comment 1","comment 2"]} </script>

并在组件挂载时解析它:

 var data = JSON.parse(document.getElementById('data').innerHTML);

我们刚刚为自己节省了往返服务器的时间。 我们稍后会看到权衡。

服务器端渲染到静态内容 (SSRS)

想象一下我们需要动态生成 HTML 的场景。

例如,如果我们正在构建一个在线计算器并且用户发出排序/calculate/34+15的查询(省略 URL 转义)。 我们需要处理查询、评估结果并使用生成的 HTML 进行响应。

我们生成的 HTML 在结构上非常简单,一旦生成的 HTML 被提供,我们就不需要 React 来管理和操作 DOM。

所以我们只是提供 HTML 和 CSS 内容。 您可以使用renderToStaticMarkup方法来实现这一点。

路由将完全由服务器处理,因为它需要为每个结果重新计算 HTML,尽管 CDN 缓存可用于更快地提供响应。 CSS 文件也可以被浏览器缓存,以便更快地加载后续页面。

带补液的服务器端渲染 (SSRH)

想象一下与上述相同的场景,但这次我们需要在客户端上有一个功能齐全的 React 应用程序。

我们将在服务器上执行第一次渲染并将 HTML 内容与 JavaScript 文件一起发回。 React 将重新水化服务器呈现的标记,并且从此时起应用程序将像 CSR 应用程序一样运行。

React 提供了内置的方法来执行这些操作。

第一个请求由服务器处理,随后的渲染由客户端处理。 因此,此类应用程序被称为通用 React 应用程序(在服务器和客户端上都呈现)。 处理路由的代码可能会在客户端和服务器上拆分(或复制)。

代码拆分也有点棘手,因为ReactDOMServer不支持 React。 懒惰,因此您可能必须使用可加载组件之类的东西。

还应该注意的是, ReactDOMServer只执行浅渲染。 换句话说,虽然你的组件的 render 方法会被调用,但是像componentDidMount这样的生命周期方法不会被调用。 因此,您需要重构代码以使用替代方法向组件提供数据。

这就是像 NextJS 这样的框架出现的地方。 它们掩盖了与 SSRH 中的路由和代码拆分相关的复杂性,并提供了更流畅的开发人员体验。

当涉及到页面性能时,这种方法会产生好坏参半的结果,我们稍后会注意到。

预渲染到静态内容 (PRS)

如果我们可以在用户请求之前呈现网页怎么办? 这可以在构建时完成,也可以在数据更改时动态完成。

然后,我们可以在 CDN 上缓存生成的 HTML 内容,并在用户请求时更快地提供它。

这在我们渲染内容之前称为预渲染,即用户请求。 这种方法可用于博客和电子商务应用程序,因为它们的内容通常不依赖于用户提供的数据。

使用补液 (PRH) 进行预渲染

当客户端渲染它时,我们可能希望我们的预渲染 HTML 成为一个功能齐全的 React 应用程序。

在处理第一个请求后,应用程序将像标准的 React 应用程序一样运行。 这种模式在路由和代码拆分功能方面类似于上面描述的 SSRH。

绩效矩阵

你一直在等待的时刻终于到来了。 是时候摊牌了。 让我们看看这些渲染路径中的每一个如何影响 Web 性能指标并确定获胜者。

在这个矩阵中,我们根据每个渲染路径在性能指标中的表现给它分配一个分数。

分数范围从 1 到 5:

  • 1 = 不满意
  • 2 = 差
  • 3 = 中等
  • 4 = 好
  • 5 = 优秀
TTFB
第一个字节的时间
液晶面板
最大的内容涂料
TTI
互动时间
捆绑大小
全部的
企业社会责任5
HTML 可以缓存在 CDN 上
1
多次访问服务器以获取 HTML 和数据
2
数据获取 + JS 执行延迟
2
需要在渲染之前加载所有 JS 依赖项
10
社会责任委员会4
HTML 可以缓存,因为它不依赖于请求数据
3
数据与应用程序一起加载
3
JS 必须在交互之前获取、解析和执行
2
需要在渲染之前加载所有 JS 依赖项
12
SSRS 3
HTML 在每个请求上生成并且不缓存
5
没有 JS 有效负载或异步操作
5
页面在第一次绘制后立即交互
5
仅包含必要的静态内容
18
SSRH 3
HTML 在每个请求上生成并且不缓存
4
首次渲染会更快,因为服务器渲染了第一遍
2
速度较慢,因为 JS 需要在第一次 HTML 解析 + 绘制后对 DOM 进行水合
1
渲染的 HTML + JS 依赖需要下载
10
个人退休计划5
HTML 缓存在 CDN 上
5
没有 JS 有效负载或异步操作
5
页面在第一次绘制后立即交互
5
仅包含必要的静态内容
20
公屋5
HTML 缓存在 CDN 上
4
首次渲染会更快,因为服务器渲染了第一遍
2
速度较慢,因为 JS 需要在第一次 HTML 解析 + 绘制后对 DOM 进行水合
1
渲染的 HTML + JS 依赖需要下载
12

关键要点

预渲染到静态内容(PRS) 会导致性能最高的网站,而带水合的服务器端渲染 (SSRH) 或客户端渲染 (CSR) 可能会导致效果不佳。

也可以对网站的不同部分采用多种方法。 例如,这些性能指标对于面向公众的网页可能至关重要,因此它们可以更有效地被索引,而一旦用户登录并查看私人帐户数据,它们的重要性可能会降低。

每个渲染路径都代表您要在何处以及如何处理数据的权衡。 重要的是,工程团队能够清楚地看到和讨论这些权衡,并选择能够最大限度地提高用户幸福感的架构。

进一步阅读和考虑

虽然我试图涵盖当前流行的技术,但这并不是一个详尽的分析。 我强烈建议阅读这篇文章,其中来自 Google 的开发人员讨论了其他高级技术,例如流式服务器渲染、三态渲染和动态渲染(为爬虫和用户提供不同的响应)。

在构建内容繁重的网站时,您需要考虑的其他一些因素包括需要为您的作者提供良好的内容管理系统 (CMS),以及轻松生成/修改社交媒体预览和针对不同屏幕尺寸优化图像的能力。