Использование AMP в качестве источника данных для вашего PWA
Если вы уже пользуетесь AMP, но еще не создали прогрессивное веб-приложение (PWA), ваши AMP-страницы могут значительно упростить его разработку. В этом руководстве вы узнаете, как использовать AMP в прогрессивном веб-приложении и задействовать существующие AMP-страницы в качестве источников данных.
От JSON к AMP
PWA, в своем наиболее распространенном сценарии применения, — это одностраничное приложение, которое подключается к JSON API по Ajax. JSON API возвращает наборы данных для определения структуры навигации и собственно контент для наполнения статей.
Далее вы преобразуете необработанный контент в пригодный к использованию HTML и визуализируете его на клиенте. Поскольку этот процесс является ресурсоемким и часто сложным в сопровождении, можно пойти другим путем — задействовать в качестве источника контента уже существующие AMP-страницы. И, что особенно важно, AMP позволяет осуществить это всего несколькими строчками кода.
Включение Shadow AMP в ваше прогрессивное веб-приложение
Первый шаг — включить в ваше прогрессивное веб-приложение специальную версию AMP, которую мы называем Shadow AMP. Да, это не ошибка — вы загружаете библиотеку AMP на странице верхнего уровня, но по факту она не будет контролировать контент верхнего уровня, а будет лишь «улучшать» те части страницы, которые вы выберете.
Добавьте Shadow AMP в шапку своей страницы, например так:
<!-- Asynchronously load the AMP-with-Shadow-DOM runtime library. --> <script async src="https://cdn.ampproject.org/shadow-v0.js"></script>
Как узнать, что API Shadow AMP готов к использованию?
Мы рекомендуем загружать библиотеку 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
, который выполняет обратные вызовы незамедлительно.
Создание навигации по вашему прогрессивному веб-приложению
Это еще один шаг, который нужно выполнить вручную. В конце концов, именно вам решать, как в вашей концепции навигации будут представлены ссылки на контент (списки, набор карточек или что-то еще).
Обычный сценарий выглядит так: вы загружаете некий JSON-файл, содержащий упорядоченные URL с определенными метаданными. Вы также получаете функцию обратного вызова, которая срабатывает, когда пользователь нажимает на одну из ссылок, и этот обратный вызов должен включать URL-адрес запрошенной AMP-страницы. Если все это уже присутствует, вы готовы к последнему этапу.
Использование API Shadow AMP для встроенного рендеринга страницы
И наконец, чтобы отобразить контент после действия пользователя, пора загрузить нужный 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-страница отображается как дочерний элемент вашего прогрессивного веб-приложения.
Приберите за собой
Скорее всего, в рамках вашего прогрессивного веб-приложения пользователь будет переходить от одной AMP-страницы к другой. При уходе с ранее отрендеренной AMP-страницы обязательно уведомляйте об этом библиотеку AMP; это делается следующим образом:
// ampedDoc is the reference returned from AMP.attachShadowDoc ampedDoc.close();
Так вы сообщаете AMP, что больше не используете этот документ, что дает возможность высвободить память и ресурсы процессора.
Просмотр в действии
Увидеть паттерн «AMP в PWA» в действии можно в созданном нами примере на React. Он демонстрирует плавные переходы во время навигации и поставляется с простым компонентом React, в который включены описанные выше шаги. То, что вы увидите, является объединением лучших особенностей обеих технологий — гибкий, настраиваемый JavaScript в прогрессивном веб-приложении и AMP для предоставления контента.
- Получить исходный код можно здесь: https://github.com/ampproject/amp-publisher-sample/tree/master/amp-pwa
- В автономном режиме компонент React можно использовать через npm: https://www.npmjs.com/package/react-amp-document
- Посмотреть его в действии можно здесь: https://choumx.github.io/amp-pwa/ (рекомендуем запускать на мобильном телефоне или эмуляторе)
Вы также можете ознакомиться с примером совместной работы PWA и AMP на базе Polymer Framework. В этом примере для встраивания AMP-страниц используется amp-viewer.
- Код можно получить здесь: https://github.com/Polymer/news/tree/amp
- А увидеть его в работе — здесь: https://polymer-news-amp.appspot.com/
-
Written by @pbakaus