將 AMP 用於 PWA 的資料來源
重要事項:本文件不適用於您目前選取的格式 電子郵件!
如果您已投資 AMP 但尚未建構 Progressive Web App,您的 AMP 頁面可以大幅簡化 Progressive Web App 的開發作業。在本指南中,您將學習如何在 Progressive Web App 中使用 AMP,並將現有的 AMP 頁面作為資料來源。
從 JSON 到 AMP
在最常見的情況下,Progressive Web App 是連線至 JSON API 的單頁應用程式 (SPA)。然後,JSON API 會傳回資料集以驅動導覽,以及呈現文章的實際內容。
接著,您將繼續將原始內容轉換為可用的 HTML,並在用戶端上呈現。此程序成本高昂且通常難以維護。您可以改為重複使用現有的 AMP 頁面作為內容來源。最棒的是,AMP 讓您只需幾行程式碼即可輕鬆完成。
在您的 Progressive Web App 中加入「Shadow AMP」
第一步是在您的 Progressive Web App 中加入特殊版本的 AMP,我們稱之為「Shadow AMP」。沒錯,您要在頂層頁面中載入 AMP 程式庫,但實際上它不會控制頂層內容。它只會「強化」您告知它的頁面部分。
在您頁面的 head 中加入 Shadow AMP,如下所示
<!-- Asynchronously load the AMP-with-Shadow-DOM runtime library. --> <script async src="https://cdn.ampproject.org/shadow-v0.js"></script>
您如何得知 Shadow AMP API 何時可供使用?
我們建議您載入 Shadow AMP 程式庫時加入 async
屬性。然而,這表示您需要使用某種方法來瞭解程式庫何時完全載入並可供使用。
要觀察的正確訊號是全域 AMP
變數的可用性,而 Shadow AMP 使用「非同步函式載入方法」來協助達成此目的。請參考以下程式碼
(window.AMP = window.AMP || []).push(function(AMP) { // AMP is now available. });
這段程式碼可以運作,而且以此方式新增的任何數量的回呼都會在 AMP 可用時觸發,但為什麼呢?
這段程式碼會轉譯為
- 「如果 window.AMP 不存在,建立一個空陣列來取代其位置」
- 「然後將一個回呼函式推送至陣列中,該函式應在 AMP 準備就緒時執行」
它可以運作的原因是,Shadow AMP 程式庫在實際載入後,會意識到 window.AMP
下已經有一個回呼陣列,然後處理整個佇列。如果您稍後再次執行相同的函式,它仍然會運作,因為 Shadow AMP 會將 window.AMP
取代為自身和一個自訂的 push
方法,該方法只會立即觸發回呼。
在您的 Progressive Web App 中處理導覽
您仍然需要手動實作此步驟。畢竟,連結內容在您的導覽概念中如何呈現取決於您。許多清單?許多卡片?
在常見情況下,您會擷取一些 JSON,其中傳回已排序的網址以及一些中繼資料。最後,您應該得到一個函式回呼,該回呼在使用者按一下其中一個連結時觸發,而該回呼應包含要求的 AMP 頁面的網址。如果您有這個,就準備好進行最後一個步驟了。
使用 Shadow AMP API 以內嵌方式呈現頁面
最後,當您想要在使用者動作後顯示內容時,就該擷取相關的 AMP 文件並讓 Shadow AMP 接管。首先,實作一個函式來擷取頁面,類似於這個
function fetchDocument(url) { // unfortunately fetch() does not support retrieving documents, // so we have to resort to good old XMLHttpRequest. var xhr = new XMLHttpRequest(); return new Promise(function(resolve, reject) { xhr.open('GET', url, true); xhr.responseType = 'document'; xhr.setRequestHeader('Accept', 'text/html'); xhr.onload = function() { // .responseXML contains a ready-to-use Document object resolve(xhr.responseXML); }; xhr.send(); }); }
現在我們有了可供使用的 Document
物件,是時候讓 AMP 接管並呈現它了。取得 DOM 元素的參考,該元素充當 AMP 文件的容器,然後呼叫 AMP.attachShadowDoc()
,如下所示
// This can be any DOM element var container = document.getElementById('container'); // The AMP page you want to display var url = "https://my-domain/amp/an-article.html"; // Use our fetchDocument method to get the doc fetchDocument(url).then(function(doc) { // Let AMP take over and render the page var ampedDoc = AMP.attachShadowDoc(container, doc, url); });
就是這樣!您的 AMP 頁面會呈現為您整體 Progressive Web App 的子項。
自行清理
您的使用者很可能會在您的 Progressive Web App 內從一個 AMP 導覽到另一個 AMP。當捨棄先前呈現的 AMP 頁面時,請務必告知 AMP,如下所示
// ampedDoc is the reference returned from AMP.attachShadowDoc ampedDoc.close();
這會告知 AMP 您不再使用此文件,並將釋放記憶體和 CPU 額外負荷。
觀看實際運作情況
您可以在我們建構的 React 範例 中看到「PWA 中的 AMP」模式的實際運作情況。它示範了導覽期間的流暢轉換,並隨附一個簡單的 React 元件,該元件包裝了上述步驟。這是兩全其美的方法 – Progressive Web App 中彈性、自訂的 JavaScript,以及驅動內容的 AMP。
- 在此處取得原始碼:https://github.com/ampproject/amp-publisher-sample/tree/master/amp-pwa
- 透過 npm 獨立使用 React 元件:https://www.npmjs.com/package/react-amp-document
- 在此處觀看實際運作情況:https://choumx.github.io/amp-pwa/ (最好在您的手機或行動裝置模擬上觀看)
您也可以看到使用 Polymer 架構的 PWA 和 AMP 範例。該範例使用 amp-viewer 來嵌入 AMP 頁面。
- 在此處取得程式碼:https://github.com/Polymer/news/tree/amp
- 在此處觀看實際運作情況:https://polymer-news-amp.appspot.com/
-
由 @pbakaus 撰寫