我们让 Shadow Reader 变得更快,并且更友好地对待搜索引擎!
我们创建了 Shadow Reader 来演示如何在渐进式网络应用程序 (PWA) 中使用 AMP 页面(阅读我们的 公告帖子 以了解更多背景信息)。该网站将 The Guardian 中现有的文章重新用于身临其境的新闻阅读器体验。它不仅仅是一个演示,而是旨在成为一个功能齐全的网站。它包含有效地将 AMP 和 PWA 相结合所需的端到端代码……它已准备好投入生产!
JS 生成的内容的 SEO
与任何自尊的单页面应用程序一样,Shadow Reader 的初始 HTML 有效负载很小。它是一个纤薄的应用程序外壳,加载速度快,在 JavaScript 加载主要内容时给用户一些东西可看。这种方法为用户带来了良好的体验!
不幸的是,它也可能给搜索引擎带来挑战。Google 将尝试执行 JavaScript 以索引最终显示给用户的内容,而不仅仅是初始 HTML。但 许多搜索引擎不会这样做或做得很不可靠。换句话说,依赖搜索引擎成功执行你的 JavaScript 并不安全。如果搜索引擎只看到应用程序外壳,而没有大部分或全部内容,它将无法正确索引页面。
如果 Shadow Reader 的文章页面在 HTML 中包含文本,并提供给搜索引擎,那不是很好吗?如果这个过程不会减慢渲染速度,而是让我们能够在不到一秒的时间内向新用户提供这些页面,那不是很好吗?
事实证明,我们可以通过向新用户提供文章的 AMP 版本来同时完成这两项工作!毕竟,网络爬虫对服务器来说也是一个新用户。那么……我们是如何做到的呢?
AMP⇒PWA
我们通过实施 AMP⇒PWA 模式来实现这一点。以下是其工作原理!
对于新用户:
- 当新用户访问文章页面时,我们会提供该文章的 AMP 版本。
- AMP 使用 <amp-install-serviceworker> 加载并安装服务工作者。
- 服务工作者加载并缓存应用外壳。
- 在下一页导航中,服务工作者处于控制之下——因此它会温和地将用户带入该下一页的 PWA。
对于现有用户,我们只需提供 PWA。
这就是我们的网站如何在同一 URL 上对新用户和现有用户进行不同处理的方式。对于现有用户,已安装服务工作者。并且,当服务工作者看到文章 URL 时,它会提供其缓存的 PWA 版本。
这在 Shadow Reader 中是如何体现的?假设用户首先访问此文章页面
https://amp.cards/theguardian/us/amazing_article
看到文章 URL,服务器会返回该文章的 AMP 版本,但当文章加载时,该版本会安装一个服务工作者。服务工作者使用 Workbox 库,包含以下行:
workboxSW.router.registerNavigationRoute('index.html')
这意味着,每当用户在此域中导航到新 URL 时,服务工作者都会看到该请求,并且不会将其传递给服务器,而是直接提供其缓存的 index.html 版本。那就是我们的 PWA。
因此,如果用户接下来点击指向
https://amp.cards/theguardian/us/another_article
服务工作程序提供缓存的 PWA HTML。但 URL 保持不变! 因此,当 PWA 查看 URL 以解析所请求的文章时,它会看到用户请求的链接,并且可以将正确的文章加载到 PWA 中。
此后,每当用户请求 Shadow Reader 链接时,服务工作程序已经安装,并且提供缓存的 PWA。
由于网络爬虫不允许我们安装服务工作程序,因此网络爬虫始终会收到 AMP 文章。
下面是该流程的精美图表
对于 新用户:
- 浏览器从服务器请求文章 URL。服务器返回包含 <amp-install-serviceworker> 的文章的 AMP 版本。
- AMP 的 serviceworker JS 导致浏览器请求服务工作程序。服务器将 service worker JS 发送到浏览器。浏览器安装服务工作程序并启动它。
- 服务工作程序向服务器发送 PWA 应用外壳的请求。服务器将这些资源发送到服务工作程序,后者会缓存它们。
对于 现有用户:
- 浏览器发送文章 URL 的请求。此请求被服务工作程序拦截。服务工作程序将缓存的 PWA 返回到浏览器。
- PWA 请求 AMP 文章。此请求到达服务器,服务器将 AMP 文章返回到 PWA。PWA 处理并显示该文章。
请记住,网络爬虫始终是新用户!
下一步是什么?
现在 Shadow Reader 有了自己的服务器,我们有一些新的待办事项
- 将来,我们可以完全放弃 YQL,直接使用 Guardian 的 RSS 源。
- 我们还应该用 Shadow Reader 链接替换 Guardian 的顶部导航链接。
- 我们要求 AMP 缓存下载并运行 iframe 中的整个 Shadow Reader: <amp-install-serviceworker data-iframe-src=”https://amp.cards/index.html“>。对普通用户来说,指定一个较小的页面可能更友好。
- Backend.js现在在服务器和前端中使用,并且我们这样做的方式有点不规范。也许我们应该重构我们的代码以使用 ECMAScript 模块?
请尝试一下,查看 github 上的代码,并告诉我们您的想法! 我们很好奇您如何尝试在自己的网站上使用 AMP/PWA 模式,我们很乐意了解您对 Shadow Reader 改进的意见。
发布者:Google 开发者倡导者 Ben Morss