將 AMP 作為您 PWA 的資料來源
重要事項:本文件不適用於您目前選取的格式 stories!
如果您已投入 AMP 但尚未建立漸進式網路應用程式,您的 AMP 頁面可以大幅簡化您漸進式網路應用程式的開發。在本指南中,您將學習如何在您的漸進式網路應用程式中使用 AMP,並將您現有的 AMP 頁面作為資料來源。
從 JSON 到 AMP
在最常見的情況下,漸進式網路應用程式是透過 Ajax 連接到 JSON API 的單頁應用程式。然後,此 JSON API 會傳回資料集,以驅動導覽和呈現文章的實際內容。
然後,您將繼續並將原始內容轉換為可用的 HTML,並在用戶端上呈現。此流程成本高昂且通常難以維護。相反地,您可以重複使用您現有的 AMP 頁面作為內容來源。最棒的是,AMP 使這一切變得輕而易舉,只需幾行程式碼即可完成。
在您的漸進式網路應用程式中包含「Shadow AMP」
第一步是在您的漸進式網路應用程式中包含我們稱之為「Shadow AMP」的特殊 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 何時準備好可以使用?
我們建議您使用 async
屬性載入 Shadow AMP 函式庫。然而,這表示您需要使用某種方法來瞭解函式庫何時完全載入並準備好使用。
要觀察的正確訊號是全域 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
方法,該方法只會立即觸發回呼。
處理您的漸進式網路應用程式中的導覽
您仍然需要手動實作此步驟。畢竟,如何呈現導覽概念中的內容連結取決於您。許多清單?一堆卡片?
在常見的情況下,您會提取一些 JSON,這些 JSON 會傳回帶有一些中繼資料的已排序 URL。最後,您應該得到一個回呼函式,該函式在使用者點擊其中一個連結時觸發,並且該回呼應包含所請求 AMP 頁面的 URL。如果您有這個,您就已為最後一步做好準備。
使用 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 接管並呈現它了。取得對作為 AMP 文件容器的 DOM 元素的參考,然後呼叫 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 頁面呈現為您整體漸進式網路應用程式的子項。
自行清理
您的使用者很可能會在您的漸進式網路應用程式中從 AMP 導覽到 AMP。當捨棄先前呈現的 AMP 頁面時,始終確保告知 AMP,如下所示
// ampedDoc is the reference returned from AMP.attachShadowDoc ampedDoc.close();
這會告知 AMP 您不再使用此文件,並將釋放記憶體和 CPU 額外負荷。
觀看實際運作
您可以在我們建置的 React 範例中看到「PWA 中的 AMP」模式的實際運作。它示範了導覽期間的流暢轉換,並隨附一個簡單的 React 元件,該元件包裝了上述步驟。這是兩全其美的方法 – 漸進式網路應用程式中彈性、自訂的 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 撰寫