Ускорение сайтов: принципы работы Progressive Web AMP
Николай Мациевский продолжает серию статей об оптимизации сайтов и приложений. Сегодня рассказывает о технологиях Progressive Web Applications.
Пол Бакауса, разработчика в команде Google AMP, написал статью «Что такое PWA». Статья от технического специалиста, а потому не всё просто для понимания. В то же время раскрыты главные принципы работы PWA, который помогает ускорять сайты.
Предлагаем перевод.
Если вы следите за публикациями на тему веб-разработок, то наверняка читали про Progressive Web Applications (PWA). Это название групп приложений с теми же возможностями, что и у обычных мобильных приложений: возможность работы без подключения к интернету, Retina-ready, возможность установки приложения, полноформатные изображения, поддержка входа и индивидуальных настроек, быстрая и гладкая прокрутка страниц, push-уведомления и удобный интерфейс.
Идет регистрация агентств-участников в рейтинги RUWARD 2024!
До 8 декабря идет этап регистрации диджитал-агентств/продакшенов в серии из 46 рейтингов узких диджитал-специализаций Руварда. Поторопитесь! =)
Несколько PWA, представленных Google для примера
Service Worker API позволяет кэшировать почти все ресурсы вашего приложения, обеспечивая почти мгновенную последовательную загрузку. Ведь первая загрузка формирует главное впечатление от приложения. Если что-то грузится дольше 3 секунд, то 53% пользователей уходят не дождавшись.
Но и 3 секунды — это непростая цель. В мобильных сетях задержки по 300 миллисекунд не редкость, и в нашем распоряжении может в итоге остаться только 1 секунда, чтобы открыть приложение.
Задержки, которые отделяют ваших пользователей от вашего контента
Конечно, есть способы смягчить проблему медленной первой загрузки — предварительная компоновка страницы приложения на сервере, загрузка функциональных элементов по принципу lazy-load функциональных элементов и т.п., но в таком случае нужно или нанимать эксперта по оптимизации страниц или самому быть экспертом.
Accelerated mobile pages (AMP)
Преимущество сайтов перед приложением — лёгкий, быстрый вход. Сайт не нужно устанавливать, а контент сразу загружается. По сути всё доступно на расстоянии клика.
Но для этого надо, чтобы сайт был действительно быстрым. Как этого добиться? Просто — строгая диета: никаких мегабайтных фотографий, никаких скриптов с миллионом строчек кода, никакой блокирующей загрузку рекламы, только контент.
Для этого созданы Accelerated Mobile Pages (AMP). Они строятся на ряде строгих правил, и их структура достаточно статична. Благодаря такой строгой структуре, платформы наподобие Google Search помогут открыть такую страницу практически мгновенно за счёт предварительной загрузки содержимого первой страницы.
Первое изображение и заголовок этой страницы будут пререндерены (предварительно отрисованы), и потому посетитель увидит их практически мгновенно
AMP или PWA?
Чтобы сайт грузился быстро, приходится мириться с некоторыми ограничениями AMP. AMP не годится, если нужны динамические элементы контента. Например, при обработке веб-платежей или подписке на push-уведомления. Также AMP-страницы плохо поддерживают Javascript. Страницы AMP загружаются из AMP-кэша Google и потому лишены большинства достоинств PWA, поскольку Service Worker не может быть запущен. С другой стороны, PWA никогда не будут такими же быстрыми при первой загрузке, как AMP.
Как только посетитель покидает AMP-кэш, нажав на внутреннюю ссылку, тут же можно устанавливать Service Worker, расширяя возможности сайта и делая его доступным без интернета
Возможно ли объединить достоинства обоих подходов в одном?
Идеальный пользовательский путь
Важно, чтобы пользователь пользователю было приятно и удобно находиться на сайте или в приложении, — его путь должен быть примерно таким:
1. Пользователь находит ссылку на ваш контент и кликает на неё.
2. Контент грузится практически мгновенно и с удовольствием изучается пользователем.
3. Пользователю предлагаются и затем автоматически устанавливаются дополнительные функции, — с push-уведомлениями, работающей без задержек навигацией, поддержкой офлайна и т.п.
4. Пользователь говорит «О! Прикольно!» и получает похожую по возможностям на обычное приложение функциональность сайта. Теперь он может сохранить его на экран своего смартфона так же, как и обычное приложение.
Первый переход по ссылке на ваш сайт должен осуществляться практически мгновенно, а просмотр страниц — должен доставлять удовольствие.
Может быть, как раз это и станет возможным, если объединить две, казалось бы, таких разных технологии?
Различные PWAMP-комбинации
Объединить PWA и AMP можно несколькими способами:
-
AMP как PWA
Когда ограничения AMP для вас некритичны. -
AMP переходит в PWA
Когда вам нужен плавный переход от одного к другому. -
AMP внутри PWA
Когда вы хотите использовать уже существующие AMP как источники данных для PWA.
AMP как PWA
Многим сайтам особо и не нужно выходить за пределы ограничений AMP. Сайт Amp by Example, например, — одновременно AMP и PWA.
-
Он использует Service Worker, и потому его можно просматривать без интернета,
-
В коде есть манифест, выдающий баннер «Добавить на домашний экран».
Когда пользователь приходит на Amp by Example из поиска Google и нажимает на какую-то внутреннюю ссылку на сайте, он уходит из Google-кэша страниц AMP и начинает взаимодействовать с оригинальным сервером. Сайт по-прежнему выдает контент в формате страниц AMP, но теперь, работая с сервером, он может загружать Service Workers, предлагать установить сайт как приложение.
Это можно использовать для того, чтобы организовать офлайн доступ к вашим AMP-страницам или же расширить их функционал, подгрузив с сервера то, что вам нужно, просто изменив заголовки с помощью события fetch у Service Workers.
function createCompleteResponse (header, body) {
return Promise.all([
header.text(),
getTemplate(RANDOM STUFF AMP DOESN’T LIKE),
body.text()
]).then(html => {
return new Response(html[0] + html[1] + html[2], {
headers: {
’Content-Type’: ’text/html’
}
});
});
}
Этот способ помогает вставлять в страницы скрипты, а также добавить на сайт дополнительную функциональность, выходящую за пределы формата AMP.
AMP переходит в PWA
Когда вышеописанного недостаточно, и вы хотите более серьёзного перехода к возможностям PWA, можно использовать более сложный способ:
-
Страницы с конкретным контентом (не обзорные, не страницы рубрик, а, например, страницы статей) загружаются в формате AMP.
-
На этих страницах размещается специальный тэг AMP <amp-install-serviceworker> в то время, пока вы просматриваете контент страницы, в фоне подгружаются оболочка PWA, кэш страниц и т.п.
-
Когда пользователь нажимает на следующую ссылку на странице, Service Worker перехватывает это событие и вместо страницы загружает приложение PWA.
Всё это делается в три несложных действия.
Первое, добавьте Service Worker на все ваши страницы AMP:
<amp-install-serviceworker
src="https://www.your-domain.com/serviceworker.js"
layout="nodisplay">
</amp-install-serviceworker>
Второе, установив Service Worker, подгрузите в кэш всё, что нужно для работы PWA:
var CACHE_NAME = ’my-site-cache-v1′;
var urlsToCache = [
’/’,
’/styles/main.css’,
’/script/main.js’
];
self.addEventListener(’install’, function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log(’Opened cache’);
return cache.addAll(urlsToCache);
})
);
});
И наконец, опять же через Service Worker, перехватите навигацию и подгрузите PWA вместо AMP. (Код, приведенный здесь, сильно упрощен. Более продвинутый пример будет в конце этой статьи.)
self.addEventListener(’fetch’, event => {
if (event.request.mode === ’navigate’) {
event.respondWith(fetch(’/pwa’));
// Immediately start downloading the actual resource.
fetch(event.request.url);
}
});
Теперь каждый раз, когда пользователь кликнет по ссылке на AMP-странице, полученной из кэша AMP, Sevice Worker зафиксирует запрос navigate и. перехватив исполнение на себя, переключит пользователя на полномасштабное, уже кэшированное локально PWA-приложение.
Вы можете улучшить сайт, используя Service Worker. Если браузер не поддерживает Service Worker, пользователь просто переместится на другую страницу в AMP-кэше
В этой технологии вы используете переход от AMP к PWA при помощи Service Worker. А что будет, если браузер пользователя не поддерживает это? Для обработки такой ситуации у тега <amp-install-serviceworker> есть поля, в которых можно указать альтернативный URL для страницы с начальной загрузкой оболочки PWA.
<amp-install-serviceworker
src="https://www.your-domain.com/serviceworker.js"
layout="nodisplay"
data-no-service-worker-fallback-url-match=".*"
data-no-service-worker-fallback-shell-url="https://www.your-domain.com/pwa">
</amp-install-serviceworker>
Если все эти атрибуты правильно указаны, то нажатие на ссылку на вашей странице AMP подключит пользователю PWA вне зависимости от того, есть поддержка Service Worker в его браузере или нет.
AMP внутри PWA
Итак, теперь пользователь внутри PWA, и, скорее всего, вы используете некую навигацию, построенную на AJAX, с контентом, подгружаемым с помощью JSON. Конечно, можно и так, но обратите внимание — вам доступна вся эта безумно огромная инфраструктура, которая поддерживает две совершенно разных вещи: одна генерирует AMP-страницы и вторая предоставляет JSON API для вашего PWA.
Но давайте задумаемся о том, что такое AMP. Это способ весьма компактной организации контента, и в этом аспекте AMP годится не только для веб-сайтов. И мы можем сильно упростить конечные приложения, используя как JSON API, так и AMP как формат организации контента в наших PWA приложениях.
Страницы в формате AMP могут быть легко встроены в другой сайт или приложение. Библиотека, необходимая для поддержки AMP, загружается только один раз для всей PWA
Конечно, проще всего выдавать готовые AMP-страницы в фрейме. Но iframe довольно медленные и кроме того, их использование приводит к необходимости загружать и инициализировать AMP-библиотеку каждый раз заново.Есть более технологичный путь — использовать Shadow DOM.
Процесс при этом выглядит примерно так:
-
PWA перехватывает какой-нибудь навигационный клик.
-
PWA выдает XMLHttpRequest, запрашивая AMP-страницу.
-
Помещает ее в новый #shadow-root.
-
Вызывает библиотеку AMP: «Эй, у меня есть для тебя контент! Проверь его!» путем вызова attachShadowDoc.
При использовании этого способа библиотека AMP компилируется и загружается один раз для всего PWA, и отвечает за все теневые документы, которые прикрепляются к ней. И поскольку вы получаете контент по запросу XMLHttpRequest, вы можете модифицировать АМР-исходник перед помещением его в теневой документ. Например, для того чтобы:
-
Отрезать ненужные элементы, например, навигацию и футер
-
Добавить дополнительный контент, типа разной навязчивой рекламы и модных кнопочек
-
Заменить какой-то контент на что-то другое
Тем самым вы упрощаете своё приложение и сильно сокращаете необходимую для его поддержки инфраструктуру.
На старт, внимание, марш!
Чтобы продемонстрировать возможности теневой DOM (то есть AMP внутри PWA) команда разработчиков AMP создала демосайт The Scenic:
Код этого примера опубликован GitHub, но вся магия находится в файле amp-document.js.
Реальный пример
Пример: сайт Mic’s new PWA. Когда вы нажимаете на произвольную ссылку в меню, система запускает уже загруженное PWA, причём это происходит так быстро, что вы не замечаете перехода от веб-страницы к приложению.
Что в итоге
В итоге, сочетание AMP и PWA даёт преимущества:
-
Вне зависимости от условий, всегда приличная скорость.
-
Большие возможности для распространения (через партнеров проекта AMP).
-
Непрерывные улучшения — технологии всё ещё в стадии разработки.
-
Меньшие инвестиции в разработку.
Читать по теме:
Мнение редакции может не совпадать с мнением автора. Если у вас есть, что дополнить — будем рады вашим комментариям. Если вы хотите написать статью с вашей точкой зрения — прочитайте правила публикации на Cossa.