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

Layer0如何從React PWA自動生成AMP

About The Author

Outline

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

保持您的安培乾燥

我們在Progressive Web Apps (PWA)和Accelerated Mobile Pages (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框架都不這麼做?

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

爲了克服這一限制,我們從早期的架構決策中獲益,即預設情況下使React Storefront應用程式成爲通用(有時稱爲異構),並支援Layer0中的伺服器端渲染(SSR)。 使用SSR,在向用戶提供頁面之前,在伺服器上完成頁面呈現。 雖然我們添加SSR的主要目標是提高性能和SEO,但它還使我們能夠在伺服器上執行React Storefront應用程式,然後按照以下技術自動將HTML輸出轉換爲有效的AMP HTML。

通知Google支援AMP

實施AMP的第一步是通知Google的爬網程序存在與您的頁面等效的AMP。 通常,您需要創建單獨的頁面AMP版本,然後配置應用程式的路由器,以便在不同的URL上同時提供AMP和PWA內容。 通過React Storefront,您只需在頂級頁面組件中添加@帶Amp裝飾器即可。 React Storefront只需在URL中添加”.amp”即可自動爲任何頁面呈現有效的AMPHTML。 n ü@wAmp裝飾器利用此慣例將必要的鏈接標記添加到文檔頭。

換句話說,這是:

				
					@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頁面使您的非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要求文檔中存在某些特定元素。 其中包括根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無法跟蹤PWA/SPA的‘Phone’(電話)流量的份額

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

AMP和PWA的基礎設施

作爲實施AMP和PWA的開發人員,您可以實施兩個版本的應用,然後通過未來的更改(意味着每個修復程序都會在兩個位置變爲代碼更改)來維護它們,或者使用自動化從頁面中導出AMP內容。 在Layer0,我們選擇了後者,這對我們的客戶非常有用。 我們迄今爲止所描述的React Storefront功能只是取得成功的原因之一。 在下一期中,我們將探討此框架如何與Layer0 (Edgio)集成,以支援企業環境中的AMP。 敬請關注。