Как мы сделали RioRun, прогрессивное веб-приложение

Следуя современным трендам в JavaScript, мы - команда Guardian - искали возможность поэкспериментировать с прогрессивными веб-приложениями, или PWA. “Progressive Web App” - по существу это только маркетинговый термин (такой же как AJAX или “responsive design”) который состоит из разнообразных техник создания приложений которые смогут конкурировать с нативными с точки зрения плавности интерфейса, функциональности и удобства использования - в первую очередь поддержкой оффлайна.

Олимпийские игры дали нам понять, что возможность, которую мы искали кроется в форме RioRun, интерактивный подкаст, который отслеживает дистанцию которую вы пробегаете на улице (или на беговой дорожке) и переводит её в маршрут марафонского забега через центр Рио-де-Жанейро. Когда вы бежите вы узнаете о местности которую вы пересекаете, её историю, культуру, политику, последние новостные события, в то время как окружающие звуки, записанные в той области, играют в фоне.

Создание PWA приложения имело смысл по нескольким причинам:

  • Потому что оно использует геолокацию и должно работать через HTTPS. По этой причине мы решили создать соответствующий под-домен вместо того, чтобы отдавать приложение прямо из страницы статьи на theguardian.com (которая еще не полностью переведена на HTTPS).
  • В нем много аудиозаписей, причем некоторые из них могут начать загружаться после того как вы начали пробежку. Для людей в сельских местностях с плохим качеством связи, или тех, у кого ограниченный тариф на интернет, оффлайн поддержка может быть очень востребована.
  • Никто (по крайней мере, никто из тех кого мы знаем) не завершает это приключение на одном дыхании, так что более вероятно, что люди пройдут весь маршрут, если приложение можно легко сохранить на рабочий стол.

Однако не все было так просто.

Сервис воркеры, и как не нужно работать с ними

Сердце PWA находится в сервис воркере. Сервис воркер это JavaScript файл, который находится между браузером и сетью, отвечает на сетевые запросы (например отдавать кешированные ответы) и держит в фоне процессы такие, как пуш-уведомления.

Chrome, Firefox и Opera - все они имеют хорошую поддержку большинства API сервис воркера. Edge (раньше Internet Explorer) работает над этим. Safari - заметное исключение: пользователям iPhone и iPad придется подождать, прежде чем они смогут воспользоваться преимуществами этих новых возможностей.

Регистрация сервис воркера очень проста:

if ( 'serviceWorker' in navigator ) {
navigator.serviceWorker.register( '/service-worker.js' )
.then( function ( reg ) {
console.log( '✓ service worker ready' );
});
}

Внутри сервис воркера мы обрабатываем три события - install (случается всякий раз, когда кто-то посещает страницу впервые, или когда посетитель возвращается после того как сервис воркер был обновлен), activate (случается когда больше не остается страниц, которые нужно загрузить, и новый сервис воркер может активироваться), и fetch (случается каждый раз, когда сделан сетевой запрос)

К этому жизненному циклу приложения еще надо привыкнуть, хотя бы потому, что перезагрузка страницы не ведет себя так, как привыкли большинство веб-разработчиков. Вместо того, чтобы просто заменить устаревший сервис воркер, перезагрузка страницы будет держать его “под контролем” - т. е. перехват сетевых запросов - пока вы не закроете вкладку (и все остальные этой же страницы). Между тем, если вам нужно почистить кеш сервис воркера, вы должны сделать жесткую перезагрузку страницы. Пока вы поймете как все это устроено, оно будет казаться совершенно невыносимым.

Какое-то время, из-за непонимания что происходит мы прибегали к разного рода хакам - рандомная генерация URL сервис воркера и так далее - в попытках увидеть как отразились наши изменения.

(Мы собрали несколько из наших заметок и поделились ими, после чего поняли, что мы не одни - много людей имели такие же проблемы, несмотря на множество доступных туториалов и документаций. Совокупная площадь новых API поистине огромна, и еще предстоит выяснить облегчит ли боль екосистема библиотек для сервис воркера.)

Как только вы разберетесь в сервис воркере, результат будет почти магическим: вы загружаете страницу на телефоне, переключаете его в режим самолета, перегружаете и продолжаете использовать приложение как ни в чем не бывало.

Кеш управляет всем вокруг меня

Мы можем сделать это кешировав все файлы, которые необходимы приложению (кроме аудио файлов) внутри обработчика события install. Кеш манифест автоматически генерируется во время сборки, поэтому нам нет необходимости беспокоиться, что мы забыли добавить туда новые иконки и т.д. поскольку мы добавляем их в само приложение.

Когда мы выкатываем новую версию приложения, кешу присваивается уникальное имя, позволяя нам освободить место занятое старым кешем.

Аудио обрабатывается по разному, так как мы не хотим загружать все 92 .mp3 файла (суммарным размером 125МБ) когда приложение запускается. Вместо этого мы кешируем эти файлы прогрессивно, храня их в отдельном кеше, который остается после развертывания новой версии приложения. Кнопка “подгрузить аудио файлы” позволяет бегунам получить несколько следующих миль аудио - мы подумали, что это было бы лучше, нежели скачивать всю кучу, с того времени как браузер может удалять кеш каждый раз, когда ему понадобиться очистить память. (С момента запуска, Алекс Рассел (Alex Russell) из Google указал нам в направлении Quora API, которое позволяет запрашивать дополнительную постоянную память, но сейчас мы предпочитаем частичный подход, поскольку он менее навящивый к людям, которые еще не привыкли к таким приложениям.)

Когда аудио файл нам больше не нужен (потому что мы устанавливаем точку на маршруте с которой продолжается воспроизведение) мы можем спокойно выбросить его из кеша.

Не делайте наших ошибок, если вам нужно кешировать дополнительные данные после первоначального события install, вы можете получить доступ к API кеша сервис воркера через window.caches. Нет необходимости посылать сообщение сервис воркеру и обрабатывать полученный ответ. Это хорошо, потому что обмен сообщениями между воркерами на клиенте очень сбивает с толку.

Нет лучше места чем дом

Строка адреса, возможно, самый мощный текстовый интерфейс когда либо изобретенный, но перенос веб приложения на телефон все еще громоздкий и сложный процес. Обычно вам нужно открыть приложение браузера (один тап), переключится в режим просмотра вкладок (еще один), нажать “создать новую вкладку” (третый), тогда тапнуть в строку поиска или строку адреса (четвертый!). Тогда вам нужно вспомнить URL и правильно написать его на мелкой клавиатуре, надеясь, что авто дополнение не приведет вас к не имеющему значения адресу.

Нативные приложения имеют большое преимущество: один тап и вы в деле.

Прогрессивные веб приложения помогают сократить путь появления веб приложения на домашнем экране Android. Если присутствуют все необходимые критерии, такие как HTTPS, сервис воркер, файл манифеста, браузер предложит вам “установить” приложение, если он посчитает это уместным (сейчас достаточно, по крайней мере в Chrome, дважды побывать на странице дольше 5 минут, хотя это может быть изменено).

Манифест файл вмещает базовую информацию о приложении имя (name), стартовая страница (start_url), а также иконки (icons). В нем также можно указать настройки для того, чтобы спрятать адресную строку (сделав приложение “нативнее”) или установить и закрепить нужную ориентацию екрана (RioRun, например, работает только в портретном режиме - мы вынуждены отображать сообщение “пожалуйста поверните свой екран” когда телефон установлен горизонтально).

Эта информация также может использоваться когда вы устанавливаете приложение вручную, через опцию “Добавить на главный екран” в меню браузера.

Когда приложение установлено на домашний екран, это не только намного более простой доступ к нему постоянным пользователям, но и гораздо больше вероятность, что люди его запомнят.

Что дальше?

RioRun был довольно уникальным експериментом и мы считаем, что прогрессивные веб-приложения потенциально могут быть идеальным средством донесения информации для всех видов журналистики, и мы надеемся увидеть (и сделать) еще многое из этого в будущем.

Оригинал статьи