Vue.js 和 SEO:如何为搜索引擎和机器人优化响应式网站
已发表: 2022-03-10反应式 JavaScript 框架(例如 React、Vue.js 和 Angular)最近风靡一时,难怪它们因其灵活性、模块化和易于自动化测试而被越来越多的网站和应用程序使用。
这些框架允许人们在网站或应用程序上实现以前无法想象的新事物,但它们在 SEO 方面的表现如何? 使用这些框架创建的页面是否会被 Google 索引? 由于使用这些框架,所有或大部分页面呈现都是在 JavaScript 中完成的(并且机器人下载的 HTML 大多是空的),如果您希望您的网站被索引,它们似乎是不可行的搜索引擎,甚至通常被机器人解析。
在本文中,我将主要讨论 Vue.js,因为它是我使用最多的框架,并且在主要项目的搜索引擎索引方面我有直接的经验,但我可以假设大部分我将介绍的内容也适用于其他框架。
用 Vue.js 替换 jQuery
您是否知道您可以像合并 jQuery 一样将 Vue 合并到您的项目中——无需构建步骤? 阅读相关文章 →
问题的一些背景
索引如何工作
为了让您的网站被 Google 索引,它需要由 Googlebot(一种访问您的网站并将页面内容保存到其索引的自动索引软件)在每个页面中的链接之后进行抓取。 Googlebot 还会在网站中查找特殊的站点地图 XML 文件,以查找可能无法从您的公共站点正确链接的页面,并接收有关网站中页面更改频率和上次更改时间的额外信息。
一点点历史
直到几年前(2009 年之前),Google 还用于索引网站 HTML 的内容——不包括所有由 JavaScript 创建的内容。 众所周知,重要的链接和内容不应该由 JavaScript 编写,因为它不会被谷歌索引,这是常见的 SEO 知识,并且可能会对网站造成惩罚,因为谷歌可能会认为它是“虚假内容”,就好像网站的所有者正在尝试一样向用户展示与向搜索引擎显示的内容不同的内容,并试图愚弄后者。
例如,诈骗者将大量对 SEO 友好的内容放在 HTML 中并将其隐藏在 JavaScript 中是非常常见的做法。 谷歌一直警告不要这种做法:
“向 Googlebot 提供与普通用户看到的内容不同的内容被视为伪装,并且违反了我们的网站管理员指南。”
你可能会因此受到惩罚。 在某些情况下,你可能会因为在服务器端向不同的用户代理提供不同的内容而受到惩罚,而且在页面加载后通过 JavaScript 切换内容也会受到惩罚。 我认为这向我们表明,Google 长期以来一直在为执行 JavaScript 的网站编制索引——至少是为了比较网站的最终 HTML(在 JavaScript 执行之后)和它为索引解析的原始 HTML。 但 Googlebot 并没有一直执行 JavaScript,而且 Google 也没有将 JavaScript 生成的内容用于索引目的。
然后,鉴于越来越多地使用 AJAX 在网站上传递动态内容,Google 提出了“AJAX 爬虫方案”来帮助用户索引基于 AJAX 的网站。 非常复杂; 它基本上要求网站生成包含 AJAX 内容的页面呈现。 当谷歌请求时,服务器将提供一个页面版本,其中包含所有(或大部分)内容,这些内容将由 HTML 页面中包含的 JavaScript 动态生成——预先呈现为内容的HTML 快照。 让服务器端解决方案提供(用于所有其他目的)意味着在客户端生成的内容的过程,意味着那些想要拥有一个严重依赖于谷歌索引的 JavaScript 的网站的人必须经历很多技术上的麻烦。
例如,如果 AJAX 读取的内容来自外部 Web 服务,则必须在服务器端复制相同的 Web 服务调用,并在服务器端生成与客户端生成的相同 HTML JavaScript——或者至少是一个非常相似的。 这非常复杂,因为在 Node.js 出现之前,它需要在两种不同的编程语言中至少部分复制相同的渲染逻辑:前端的 JavaScript 和 PHP、Java、Python、Ruby 等。后端。 这被称为“服务器端渲染”,它可能导致维护地狱:如果您对在前端渲染内容的方式进行了重要更改,则必须在后端复制这些更改。
避免重复逻辑的唯一替代方法是使用执行 JavaScript 的浏览器解析您自己的站点,并将最终结果保存到您的服务器,然后将这些结果提供给 Googlebot。 这有点类似于现在所谓的“预渲染”。
Google(使用其 AJAX 抓取方案)还保证您将避免处罚,因为在这种情况下,您向 Googlebot 和用户提供不同的内容。 然而,自 2015 年以来,谷歌在一篇官方博客文章中反对这种做法,该文章告诉网站管理员以下内容:
“今天,只要您不阻止 Googlebot 抓取您的 JavaScript 或 CSS 文件,我们通常能够像现代浏览器一样呈现和理解您的网页。”
这告诉我们的并不是 Googlebot 在索引网页时突然获得了执行 JavaScript 的能力,因为我们知道它已经这样做了很长时间(至少是为了检查虚假内容和诈骗)。 相反,它告诉我们 JavaScript 执行的结果将被索引并在 SERP 中使用。
这似乎意味着我们不必再担心向 Google 提供服务器端呈现的 HTML。 但是,我们看到各种可用于 JavaScript 框架的服务器端渲染和预渲染工具,但似乎并非如此。 此外,在与大型项目的 SEO 机构打交道时,预渲染似乎被认为是强制性的。 怎么会?
Google 如何实际索引使用前端框架创建的页面?
本实验
为了查看 Google 在使用前端框架创建的网站中实际索引的内容,我做了一个小实验。 它并未涵盖所有用例,但它至少是一种了解更多有关 Google 行为的方法。 我用 Vue.js 构建了一个小型网站,并且不同部分的文本呈现不同。
该网站的内容取自 Infinite Jest Wiki 中 David Foster Wallace 对 Infinite Jest一书的描述(谢谢大家! )。 整本书有几篇介绍性文字,还有一个人物列表和他们的个人传记:
- 静态 HTML 中的一些文本,在 Vue.js 主容器之外;
- Vue.js 会立即呈现一些文本,因为它包含在应用程序代码中已经存在的变量中:它们在组件的
data
对象中定义; - #一些文本是Vue.js从
data
对象中渲染出来的,但是有300ms的延迟; - 角色 bios 来自一组 rest API,我使用 Sandbox 特意构建了这些 API。 由于我假设 Google 会执行网站的代码并在一段时间后停止以获取页面当前状态的快照,因此我将每个 Web 服务设置为以增量延迟响应,第一个为 0 毫秒,第二个为 300 毫秒,第三个为 600 毫秒,依此类推,直到 2700 毫秒。
每个角色简介都被缩短并包含一个指向子页面的链接,该子页面仅可通过 Vue.js 获得(URL 由 Vue.js 使用历史 API 生成),而不是服务器端(如果您调用直接页面,你没有得到服务器的响应),检查那些是否也被索引了。 我假设这些不会被索引,因为它们不是呈现服务器端的正确链接,而且谷歌无法直接将用户引导到这些链接。 但我只是想检查一下。
我将这个小测试站点发布到我的 Github 页面并请求索引——看看。
结果
实验结果(关于首页)如下:
- 已经在静态 HTML 内容中的内容被 Google 索引(这很明显);
- Vue实时生成的内容总是被谷歌索引;
- 由 Vue 生成,但在 300 毫秒后渲染的内容也会被索引;
- 来自 Web 服务的内容有一些延迟,可能会被编入索引,但并非总是如此。 我检查了谷歌在不同时刻对页面的索引,最后插入的内容(几秒钟后)有时会被索引,有时却没有。 快速呈现的内容在大多数情况下都会被编入索引,即使它来自对外部 Web 服务的异步调用。 这取决于 Google 对每个页面和网站的渲染预算,这取决于其内部算法,并且可能会根据您网站的排名和 Googlebot 渲染队列的当前状态而有很大差异。 因此,您不能依赖来自外部 Web 服务的内容来获取索引;
- 子页面(因为它们不能作为直接链接访问)未按预期编入索引。
这个实验告诉我们什么? 基本上,即使来自外部网络服务,Google 也会对动态生成的内容进行索引,但不能保证如果内容“到达太晚”就会被索引。 除了这个实验,我在其他真实的生产网站上也有过类似的经历。
竞争性搜索引擎优化
好的,所以内容被索引了,但这个实验没有告诉我们的是:内容会被竞争排名吗? 与动态生成的网站相比,Google 会更喜欢具有静态内容的网站吗? 这不是一个容易回答的问题。
根据我的经验,我可以看出动态生成的内容可以在 SERPS 中排名靠前。 我在一家大型汽车公司的新车型网站上工作,推出了一个具有新三级域的新网站。 该网站完全是用 Vue.js 生成的——除了<title>
标签和meta
描述之外,静态 HTML 中的内容很少。
该网站在发布后的头几天开始对次要搜索进行排名,SERP 中的文本片段报告了直接来自动态内容的单词。
在三个月内,它在与该车型相关的大多数搜索中排名第一——这相对容易,因为它托管在属于汽车制造商的官方域上,并且该域与知名网站有大量链接。
但考虑到我们不得不面对负责该项目的 SEO 公司的强烈反对,我认为结果仍然是显着的。
由于项目的最后期限紧迫且缺乏时间,我们打算在不进行预渲染的情况下发布该网站。
动画文本
谷歌没有索引的是大量动画文本。 我与之合作的一家公司 Rabbit Hole Consulting 的网站包含大量文本动画,这些动画是在用户滚动时执行的,并且需要将文本分成多个不同标签的块。
网站主页中的主要文本不适用于搜索引擎索引,因为它们没有针对 SEO 进行优化。 它们不是由技术语言制成的,也不使用关键字:它们只是为了陪伴用户进行关于公司的概念之旅。 当用户进入主页的各个部分时,文本会动态插入。
网站这些部分中的任何文本都不会被谷歌索引。 为了让 Google 在 SERP 中显示一些有意义的内容,我们在联系表单下方的页脚中添加了一些静态文本,这些内容确实作为 SERP 中页面内容的一部分显示。
页脚中的文本被编入索引并显示在 SERP 中,即使用户不会立即看到它,除非他们滚动到页面底部并单击“问题”按钮打开联系表单。 这证实了我的观点,即内容确实会被索引,即使它没有立即显示给用户,只要它很快呈现到 HTML - 而不是按需呈现或在长时间延迟后呈现。
预渲染呢?
那么,为什么要对预渲染大惊小怪——无论是在服务器端还是在项目编译时完成? 真的有必要吗? 虽然一些框架,比如 Nuxt,让它更容易执行,但它仍然不是野餐,所以选择是否设置它并不是一个轻松的选择。
我认为这不是强制性的。 如果您希望被 Google 编入索引的许多内容都来自外部 Web 服务并且在呈现时不能立即使用,并且可能(在某些不幸的情况下)根本不可用,这当然是一项要求,例如,web 服务停机。 如果在 Googlebot 访问期间您的某些内容到达太慢,则可能无法将其编入索引。 如果 Googlebot 恰好在您对 Web 服务执行维护的时刻为您的页面编制索引,它可能根本不会索引任何动态内容。
此外,我没有证据证明静态内容和动态生成的内容之间的排名差异。 这可能需要另一个实验。 我认为很有可能,如果内容来自外部网络服务并且没有立即加载,它可能会影响谷歌对您网站性能的看法,这是排名的一个非常重要的因素。
推荐阅读:移动网页设计如何影响本地搜索(以及如何处理)
其他注意事项
兼容性
直到最近,Googlebot 还使用了一个相当老的 Chromium 版本(Google Chrome 所基于的开源项目),即版本 41。这意味着 Google 无法正确呈现一些最近的 JavaScript 或 CSS 功能(例如 IntersectionObserver、 ES6 语法,等等)。
谷歌最近宣布,它现在正在 Googlebot 中运行最新版本的 Chromium(在撰写本文时为 74),并且该版本将定期更新。 Google 运行 Chromium 41 的事实可能对那些决定无视与 IE11 和其他旧浏览器的兼容性的网站产生重大影响。
您可以在此处查看 Chromium 41 和 Chromium 74 对功能支持的比较,但是,如果您的网站已经在填充缺失的功能以保持与旧浏览器的兼容性,那么应该没有问题。
始终使用 polyfill ,因为您永远不知道哪个浏览器缺少对您认为司空见惯的功能的支持。 例如,Safari 直到 2019 年 3 月发布的 12.1 版才支持像 IntersectionObserver 这样的主要且非常有用的新功能。
JavaScript 错误
如果您依靠 Googlebot 执行 JavaScript 来呈现重要内容,则必须不惜一切代价避免可能阻止内容呈现的主要 JavaScript 错误。 虽然机器人可能会解析和索引并非完全有效的 HTML(尽管在任何站点上总是最好有有效的 HTML!),但如果存在阻止加载某些内容的 JavaScript 错误,那么 Google 将无法索引那个内容。
在任何情况下,如果您依赖 JavaScript 向最终用户呈现重要内容,那么您很可能已经进行了大量的单元测试来检查任何类型的阻塞错误。 但是请记住,Javascript 错误可能来自不可预测的情况,例如,在 API 响应错误处理不当的情况下。
最好有一些实时错误检查软件(例如 Sentry 或 LogRocket),它会提醒您在单元或手动测试期间可能未选择的任何边缘情况错误。 这增加了依靠 JavaScript 获取 SEO 内容的复杂性。
其他搜索引擎
其他搜索引擎在动态内容方面的表现不如谷歌。 Bing 似乎根本没有索引动态内容,DuckDuckGo 或百度也没有。 可能这些搜索引擎缺乏谷歌所拥有的资源和计算能力。
使用无头浏览器解析页面并执行几秒钟的 JavaScript 来解析呈现的内容肯定比仅仅读取纯 HTML 更耗费资源。 或者这些搜索引擎可能出于其他原因选择不扫描动态内容。 不管是什么原因,如果您的项目需要支持这些搜索引擎中的任何一个,您需要设置预渲染。
注意:要获取有关其他搜索引擎渲染能力的更多信息,您可以查看 Bartosz Goralewicz 的这篇文章。 它有点旧,但根据我的经验,它仍然有效。
其他机器人
请记住,您的网站也会被其他机器人访问。 最重要的例子是 Twitter、Facebook 和其他社交媒体机器人,它们需要获取有关您的页面的元信息,以便在用户链接页面时显示页面的预览。 这些机器人不会索引动态内容,只会显示它们在静态 HTML 中找到的元信息。 这导致我们进入下一个考虑。
子页面
如果您的网站是所谓的“单页网站”,并且所有相关内容都位于一个主 HTML 中,那么您可以毫无问题地将该内容编入 Google 索引。 但是,如果您需要 Google 索引并显示网站上的任何二级页面,您仍需要为每个二级页面创建静态 HTML — 即使您依赖 JavaScript 框架检查当前 URL 并提供相关内容以放置在那个页面中。 在这种情况下,我的建议是创建至少提供正确title
标签和元描述/信息的服务器端(或静态)页面。
结论
我在研究这篇文章时得出的结论如下:
- 如果您只针对 Google,则不必使用预渲染来让您的网站完全编入索引,但是:
- 对于需要编制索引的内容,您不应依赖第三方 Web 服务,尤其是在他们没有快速回复的情况下。
- 您通过 Vue.js 渲染立即插入 HTML的内容确实会被编入索引,但您不应使用动画文本或在用户操作(如滚动等)后插入 DOM 中的文本。
- 确保您测试 JavaScript 错误,因为它们可能导致整个页面/部分没有被索引,或者您的网站根本没有被索引。
- 如果您的网站有多个页面,您仍然需要一些逻辑来创建页面,这些页面虽然依赖与主页相同的前端呈现系统,但可以被 Google 索引为单独的 URL。
- 如果您需要在不同页面之间为社交媒体提供不同的描述和预览图像,您也需要在服务器端或通过为每个 URL 编译静态页面来解决这个问题。
- 如果您需要您的网站在Google 以外的搜索引擎上运行,您肯定需要进行某种预渲染。