Home Blogs Layer0如何從React PWA自動生成AMP
Applications

Layer0如何從React PWA自動生成AMP

About The Author

Outline

AMPConf 2019剛剛結束,但我們剛剛開始! 在這一系列部落格文章中,我們通過強調React Storefront框架和Layer0如何使開發人員在React應用程式中支援AMP變得更輕鬆來慶祝AMPConf。

保持AMPS乾燥

我們在電子商務中相對較早地採用了漸進式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代碼庫。

只要撰寫一次優秀的應用程式就足夠困難了。 沒有人想要重複寫相同的應用程式。 開發人員非常討厭這種事情,他們給它一個流行的縮寫詞:乾(不要重複)。 作為開發人員,我們在早期投入資金,將自動AMP支援添加到我們為電子商務PWA創建的React框架中。 這樣,開發人員就可以在React中編寫漸進式Web應用程式並獲得AMP支援,而無需額外的開發工作。

而且它對我們的客戶非常有效。 使用React Storefront導入AMP通常需要一兩天時間,而不是重建他們的應用程式,而大部分時間只是驗證一切是否正常工作。

在這篇文章中,我們將介紹React Storefront如何通過單個代碼庫為您提供AMP和PWA支援。 在下一部分中,我們將分享Layer0的一些令人興奮的新功能,這些功能有助於在複雜的企業環境中提供AMP。

爲什麼沒有所有的反應框架都能做到這一點?

對於典型的React應用程式,自動導出AMP內容很困難。 這是因爲大多數React應用程序只能在瀏覽器中運行,但AMP內容在進入瀏覽器之前不能包含任何JavaScript (包括React)。 換句話說,您不能只將Google AMP暫存指向您發送到瀏攬器的同一反應代碼。 它們的格式完全不同。

為了克服這一限制,我們從早期的架構決策中獲益,該決策將React Storefront應用程式預設為通用(有時稱為異型),並在Layer0年支援伺服器端渲染(SSR)。 使用SSR時,頁面呈現在伺服器上,然後再提供給用戶。 雖然我們添加SSR的主要目標是提高性能和SEO,但它還使我們能夠在伺服器上執行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"/>
				
			

當Google的搜尋程序看到/p/1的鍊接時,它將下載AMP內容並直接從Google的AMP CDN提供。

請注意,爲了獲得正確的SEO,AMP頁面還需要將rel=canonical標記嵌入回頁面的原始PWA版本,如下所示:

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

此處值得強調的是,AMP頁和非AMP頁面必須使用適當(但不同版本的)<鍊接>標記相互指向。 如果沒有正確的設定,Google將無法提供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}/>
				
			

React框架負責在Google請求AMP頁面時呈現組件的AMP版本。

條件渲染

在大多數情況下,開發人員只需使用React Storefront框架內的一個AMP感知組件,即可在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屬性和鍊接rel=“stylesheet”。 React Storefront將嵌入多個<樣式>元素甚至內嵌樣式屬性的所有代碼庫樣式整合到單個<樣式amp自定義>元素中。 對於樣式屬性的每次使用,React Storefront都會創建一個包含相應規則的唯一CSS類,將類應用到元素,刪除樣式屬性,並將類添加到amp-custom樣式元素。 換句話說,這是:

				
					<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的‘Phone’流量共享

如果使用組件庫,則組件呈現的某些HTML可能會由於各種原因與AMP驗證器相衝突。 React Storefront鼓勵使用廣受歡迎的材料UI庫,並提供清理它生成的HTML的特定規則。 在這種情況下,使用全面的反應漸進式Web應用程式框架,涵蓋從狀態管理到組件和樣式的所有內容,真正顯示了它在提高開發人員速度方面的價值。

AMP和PWA的基礎設施

作為實施AMP和PWA的開發人員,您可以實施應用程式的兩個版本,然後在未來的更改中進行維護(意味著每個修復都會在兩個位置變成代碼更改),或者使用自動化從頁面派生AMP內容。 在Layer0年,我們選擇了後者,這對我們的客戶非常有用。 我們到目前爲止所介紹的React Storefront功能只是成功的一部分原因。 在下一部分中,我們將探討此框架如何與Layer0 (Edgio)集成,以便在企業環境中支持AMP。 敬請關注。