Home Blogs Layer0如何从React PWA自动生成AMP
Applications

Layer0如何从React PWA自动生成AMP

About The Author

Outline

AMPConf 2019即将结束,但我们刚刚开始! 在这一系列博客文章中,我们通过强调React Storefront框架和Layer0如何让开发人员更轻松地在React应用中支持AMP来庆祝AMPConf。

保持安培干燥

我们在电子商务方面相对较早地采用了渐进式Web应用程序(PWA)和加速移动页面(AMP)。 借助React支持的PWA,开发人员可以在Web上提供与本地应用程序相媲美的极具吸引力的体验。 但是,当涉及到搜索生成的流量时,AMP提供了最快的可能选项。

事实上,Google推荐的客户旅程是首先交付应用程序的AMP版本,以便搜索用户并在后续页面上过渡到网站的完整PWA版本。 由于近一半的零售商网站流量来自有机搜索,因此支持AMP和PWA已成为首要任务。

不幸的是,PWA和AMP技术的差异再大不过了。 PWA使用React,Vue和Angular等现代库,其中JavaScript扮演着渲染HTML和CSS以及提供交互性的核心角色。 另一方面,AMP页面完全禁止使用JavaScript,并且对CSS和HTML都有严格的限制。 结果是,要同时支持AMP和PWA,开发人员通常需要在AMP中重新编码其应用的很大一部分。 开发团队的负担并不止于此。 每个错误修复,布局更改,新功能等都可能需要传播到AMP和PWA代码库。

编写一个伟大的应用程序一次是足够困难的。 没有人想写同一个应用程序两次。 开发者非常讨厌这种东西,他们给它一个流行的缩写,干燥(不要重复自己)。 作为开发者,我们在早期投资于为电子商务PWA创建的React框架中添加了自动AMP支持。 这样,开发人员就可以编写渐进式Web应用程序,无需额外的开发工作即可获得AMP支持。

这对我们的客户非常有效。 通过React Storefront实施AMP通常需要我们的客户花费一两天时间,而不是重建他们的应用程序,而大部分工作只是验证一切是否正常。

在这篇文章中,我们将介绍React Storefront如何通过单一代码库为您提供AMP和PWA支持。 在下一期中,我们将分享Layer0的一些令人兴奋的新功能,这些功能有助于在复杂的企业环境中交付AMP。

为什么不是所有React框架都这样做?

对于典型的React应用程序,自动派生AMP内容很困难。 这是因为大多数React应用程序设计为仅在浏览器中运行,但AMP内容在进入浏览器之前不能包含任何JavaScript(包括React )。 换句话说,您不能只将Google AMP缓存指向您发送到浏览器的相同React代码。 它们是完全不同的格式。

为了克服这一局限性,我们从早期的体系结构决策中获益匪浅,即默认情况下使React Storefront应用程序成为通用应用程序(有时称为同构应用程序),并在Layer0中支持服务器端渲染(SSR)。 使用SSR,页面的呈现在服务器上完成,然后再提供给用户。 虽然我们添加SSR的主要目标是提高性能和搜索引擎优化,但它也使我们能够在服务器上运行React Storefront应用程序,然后按照以下技术自动将HTML输出转换为有效的AMP HTML。

通知Google AMP受支持

实现AMP的第一步是通知Google的爬虫您的页面存在AMP等效物。 通常,您需要为页面创建单独的AMP版本,然后配置应用程序的路由器,以在不同的URL上同时提供AMP和PWA内容。 使用React Storefront,您只需将@with Amp decorator添加到顶级页面组件即可。 React Storefront只需在URL中添加”.amp”,即可自动呈现任何页面的有效AMPHTML。 n ü@with Amp Decorator利用此约定将必要的链接标签添加到文档头。

换句话说,这是:

				
					@withAmp
class Product extends Component {
  ...
}
				
			

在您的PWA页面上会出现类似的结果:

				
					<link rel="amphtml" href="https://www.mysite.com/p/1.amp"/>
				
			

当谷歌的爬虫看到/p/1的链接时,它将下载AMP内容并直接从谷歌的AMP CDN提供服务。

请注意,为了正确的SEO,AMP页面还需要将REL=Canonical标记嵌入到页面的原始PWA版本,如下所示:

				
					<link rel="canonical" href="https://www.mysite.com/p/1"/>
				
			

这里值得一提的是,AMP和非AMP页面之间使用适当(但不同版本的)<链接>标记相互指向对方的重要性。 如果没有这些正确的设置,Google将无法提供您的AMP内容,更糟糕的是,它可能导致您的AMP页面清除您的非AMP页面的SEO排名。 React Storefront为您完成所有”AMP双项簿记”,因此您不必仅仅因为有人忘记更新正确的标签而担心发生这种情况。

AMP感知组件

即使在AMP中实现最基本的交互性也可能是一个巨大的难题。 例如,AMP中的简单数量字段可能如下所示:

				
					<amp-form>
<amp-state id="product">
<script type="application/json">
      {
        "id": "123",
        "name": "Product",
        "quantity": 1
      }
</script>
</amp-state>
<input
    type="text"
    [value]="product.quantity"
    on="input-throttled:AMP.setState({ product: { quantity: event.value } })"
  />
</amp-form>
				
			

想象一下,渐进式Web应用中的每个交互式控件编写两个版本的代码。 您的发布截止日期已经到了!

谢天谢地,我们已经为您完成了这项艰苦的工作。 React Storefront为您提供粗糙粒度的AMP感知组件,如QuantitySelector,可隐藏所有这些华丽细节。 在React Storefront中,您只需使用:

				
					<QuantitySelector product={product}/>
				
			

当Google请求AMP页面时,React框架负责渲染组件的AMP版本。

条件渲染

在大多数情况下,开发人员只需使用React Storefront框架中的一个AMP感知组件,即可在AMP中提供交互性。 但是,如果您发现需要呈现特定于AMP的内容,则框架将在应用状态中公开一个布尔放大器字段,您可以使用该字段在AMP中有条件呈现特定内容。

例如:

				
					import React, { Component } from 'react'
import { inject } from 'mobx-react'
@inject('app')
class MyAMPAwareComponent extends Component {
  render() {
    if (this.props.app.amp) {
      return (
        // AMP content
      )
    } else {
      return (
        // PWA content
      )
    }
  }
}
				
			

通用分析

AMP定义交互作用事件的声明方式与React完全不同。 例如,假设您希望通过向Google Analytics发送事件来跟踪特定产品链接的点击情况。 在AMP中,这类似于:

				
					<amp-analytics type="googleanalytics">
<script type="application/json">
    {
      "triggers": [
        {
          "on":"click",
          "event":"product_clicked",
          "selector":"#product1",
          "request":"event",
          "productID": "1"
        }
      ]
    }
</script>
</amp-analytics>
<a id="product1" href="/p/1" alt="Red Shirt">
<amp-img src="/images/products/1" height="100" width="100"/>
<div>Red Shirt</div>
</a>
				
			

我会省去你的React实现,但它很可能涉及到onClick侦听器和几个对GA ()的调用。 只需说两者看起来没有什么相似之处就够了。

React Storefront提供了一个抽象,即Track组件,可为您实现这两个目标:

				
					<Track event="product_clicked" productID={product.id}>
<a href="/p/1" alt="Red Shirt">
<Image src="/images/products/1"/>
<div>Red Shirt</div>
</a>
</Track>
				
			

将服务器呈现的HTML转换为AMPHTML

上述策略为我们提供了大约80%的有效AMP呈现方式。 但是,还需要对文档进行其他更改。 React Storefront会在发送前对传出的HTML进行转换,并进行多项更改,包括:

添加amp-boilerplate,然后⚡

AMP要求文档中包含一些特定元素。 其中包括⚡根HTML元素上的””属性和称为AMP样板文件的标准样式元素:

				
					<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal
				
			

转变和整合CSS

AMP要求在单个样式元素的正文中提供所有CSS。 <>禁止使用style属性和link rel=”stylesheet”。 React Storefront将代码库中嵌入多个样式<>元素甚至内联样式属性的所有样式整合到一个<样式和自定义>元素中。 对于每次使用Style属性,React Storefront都会创建一个包含相应规则的唯一CSS类,将该类应用到元素,删除Style属性,并将该类添加到amp-custom Style元素。 换句话说,这是:

				
					<div style="font-weight:bold">Red Shirt</div>
				
			

变为:

				
					<style amp-custom>
  …
  .mi1 {
    font-weight:bold;
  }
</style>
<div class="mi1">Red Shirt</div>
				
			

在您的所有样式中添加此CSS的自动转换功能后,在从React应用编写AMP兼容页面时,消除了另一个令人头疼的问题。

正在清除标记

AMP对标记施加了各种其他规则。 例如,ReactDOM呈现布尔属性的方式产生无效的AMPHTML。 此JSX:

				
					<script
  async
  custom-element="amp-sidebar"
  src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"
/>
				
			

将生成以下HTML:

				
					<script
  async
  custom-element="amp-sidebar"
  src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"
/>
				
			

这会导致AMP验证器显示如下错误:

Crux无法跟踪PWAS/SPA的”电话”流量份额

如果使用组件库,则由于各种原因,组件呈现的某些HTML可能会与AMP验证器相冲突。 React Storefront鼓励使用广受欢迎的材料UI库,并提供了清理其生成的HTML的特定规则。 这就是使用全面的React渐进式Web应用程序框架的地方,该框架涵盖了从状态管理到组件和样式设计的所有内容,真正展现了它在提高开发人员速度方面的价值。

AMP和PWA的基础设施

作为实施AMP和PWA的开发者,您可以实施应用的两个版本,然后通过将来的更改来维护它们(这意味着每个修复程序都会在两个位置变成代码更改),或者使用自动化从您的页面派生AMP内容。 在Layer0,我们选择了后者,它非常适合我们的客户。 我们迄今为止介绍的React Storefront功能只是成功的一部分原因。 在下一期中,我们将探讨此框架如何与Layer0 (Edgio)集成,以在企业环境中支持AMP。 敬请期待。