В Google Play есть одно приложение, разработанное Chilango Lab, у которого больше миллиона загрузок и довольно высокий рейтинг. Называется оно Nothing, что можно перевести как «Ничто», и замечательно оно тем, что не делает абсолютно ничего. В нём, правда, спрятана приятная пасхалка, но это не меняет дела. Если проанализировать это приложение, то окажется, что его размер — 14 Мб, при установке оно занимает 19,24 Мб.


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

Ему это удалось. А именно, он воссоздал функционал Nothing, используя HTML, CSS и JavaScript, оформив его в виде прогрессивного веб-приложения (PWA, Progressive Web App). Оно работает без подключения к интернету, вызывать его можно, как и обычное приложение, с главного экрана. Основная разница между обычным Android-приложением и его PWA-копией заключается в размерах. Первое, напомним, занимает на устройстве 19,24 Мб. Второе — 205 Кб.


Обычное приложение и PWA

Создание значков для Nothing


Прежде чем я расскажу вам о коде, создадим значок для PWA Nothing. Для решения этой задачи я воспользовался отличным опенсорсным инструментом Launcher Icon Generator.


Launcher Icon Generator

С помощью Launcher Icon Generator мне удалось создать значок для моего варианта Nothing буквально мгновенно. Программа автоматически генерирует значки различных размеров.

PWACompat


После того, как работа над значком была завершена, мне нужно было создать манифест веб-приложения. Благодаря ему браузер Chrome для Android покажет экран-заставку при загрузке PWA. Можно ли сделать так, чтобы такой экран появлялся и в других браузерах? Да, можно, и для этого нам понадобится библиотека PWACompat, которая позволяет реализовать именно то, что нам нужно. Её, вместе с манифестом, достаточно подключить в коде PWA:

<link rel="manifest" href="manifest.json" />
<script async src="https://cdn.jsdelivr.net/npm/pwacompat@2.0.6/pwacompat.min.js"
    integrity="sha384-GOaSLecPIMCJksN83HLuYf9FToOiQ2Df0+0ntv7ey8zjUHESXhthwvq9hXAZTifA"
    crossorigin="anonymous"></script>

Вот как выглядит экран-заставка в браузере Safari (iOS).


Экран-заставка в Safari

Но этим возможности PWACompat не ограничиваются. В частности, эта библиотека позволяет создавать мета теги для различных браузеров, описывающие то, как должно открываться PWA, а также устанавливает цвет темы, основываясь на манифесте веб-приложения.

Добавление приложения на главный экран


Одна из моих любимых возможностей PWA называется A2HS (Add to Home screen, добавить на главный экран), благодаря ей можно добавить значок для запуска приложения на главный экран. Однако начиная с Chrome 68 на Android, вместо большого A2HS-баннера, теперь выводится небольшая информационная панель с соответствующим предложением.


Прощай A2HS-баннер (Chrome 67 и более ранние версии)

В любом случае, информационная панель — это промежуточное решение, когда-то эту возможность из Chrome уберут. Поэтому мне нужно было создать более приятный A2HS-интерфейс для PWA Nothing.


Кнопка Install (слева), кнопка Install и A2HS-панель (в центре), диалоговое окно Add to Home Screen (справа)

В данном случае, если браузер поддерживает возможность добавления приложения на главный экран, он выведет, в верхней части страницы, кнопку Install. Когда пользователь щёлкает по этой кнопке, вызывается диалоговое окно Add to Home Screen.

Вот соответствующий код.

var installPromptEvent;
var btnInstall = document.querySelector('#install');

window.addEventListener('beforeinstallprompt', function (event) {
    event.preventDefault();
    installPromptEvent = event;
    btnInstall.removeAttribute('disabled');
});

btnInstall.addEventListener('click', function () {
    btnInstall.setAttribute('disabled', '');
    installPromptEvent.prompt();
    installPromptEvent.userChoice.then((choice) => {
        if (choice.outcome === 'accepted') {
            console.log('User accepted the A2HS prompt');
        } else {
            console.log('User dismissed the A2HS prompt');
        }
        installPromptEvent = null;
    });
});

Если сайт соответствует критериям A2HS, то браузер вызовет событие beforeinstallprompt.

Пасхалка


Внимание, тут будет спойлер!


Собственно говоря, пасхалка PWA Nothing — это код Konami и 10-часовое видео на YouTube.


Вызов пасхалки (вверх, вверх, вниз, вниз, влево, вправо, влево, вправо и два касания)

После того, как пользователь справится с кодом, PWA откроет это видео.

Для добавления поддержки кода Konami в моё приложение я воспользовался библиотекой Konami-JS. Она невелика, с ней легко работать, и она, кроме прочего, поддерживает мобильные устройства. Тут кроется единственное различие между моим PWA и исходным приложением для Android. В частности, там, где у меня, при вводе кода, надо выполнить два касания, в исходном приложении нужно воспользоваться панелью с кнопками.

Отключение обновления страницы при протягивании


У меня, в процессе работы над приложением, возникла небольшая проблема. Когда пользователь пытается протянуть страницу вниз на мобильном устройстве, это вызывает выполнение обновления страницы (pull-to-refresh). Мне это не нужно.


Нежелательное обновление страницы

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

overscroll-behavior-y: contain

Хостинг


В качестве хостинга для PWA Nothing была выбрана площадка Netlify. Это универсальная платформа для современных веб-проектов. Причина, по которой я решил разместить моё приложение на Netlify, заключается в том, что тут всё очень легко настраивается. Кроме того, всё это бесплатно.


Панель управления Netlify

Для развёртывания проекта на Netlify можно воспользоваться одним из трёх методов. Речь идёт об инструментах командной строки, о ручном развёртывании, и о непрерывном развёртывании.

?Инструменты командной строки Netlify


Это классический способ развёртывания веб-проектов. Для того чтобы им воспользоваться, надо установить CLI Netlify, войти в свою учётную запись, инициализировать проект и развернуть его. Выглядит это так:

> brew tap netlify/netlifyctl 
> brew install netlifyctl
> netlifyctl login
> netlifyctl init
> netlifyctl deploy

?Ручное развёртывание


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


Ручное развёртывание

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

?Непрерывное развёртывание


Сейчас я использую именно этот метод. После того, как я связал свой GitHub-репозиторий с Netlify, когда я отправляю туда код, Netlify автоматически собирает и развёртывает проект. Волшебство, не иначе.

?HTTPS


Так как PWA должны обслуживаться по HTTPS из защищённого источника, мне нужно было обеспечить, чтобы на моём сайте был бы включен HTTPS. Мне, правда, не пришлось прилагать особых усилий в этой области, так как Netlify предоставляет бесплатный HTTPS для всех доменов, включая собственные домены пользователей.


HTTPS

Более того, с панели управления Netlify можно включить принудительный переход на HTTPS (HSTS). Это обеспечит постоянную защиту сайта.

Анализ проекта с помощью Lighthouse


Lighthouse — это опенсорсный автоматизированный инструмент для улучшения качества веб-страниц. С его помощью можно проанализировать любую страницу — общедоступную, или требующую аутентификации. Он, кроме прочего, позволяет анализировать производительность и доступность страниц, исследовать прогрессивные веб-приложения.


Lighthouse

Моему приложению удалось набрать 97 баллов по показателю производительности и по 100 баллов по остальным показателям. Вот полный отчёт.

Итоги


Как видите, прогрессивное веб-приложение, которое ничего не делает, оказывается гораздо меньше Android-приложения, обладающего столь же богатой функциональностью. Здесь можно испытать PWA Nothing. А здесь можно найти его исходный код.

Уважаемые читатели! Как вы думаете, какие используемые вами приложения для Android стоило бы воссоздать в форме PWA?

Комментарии (8)


  1. evocatus
    27.08.2018 12:43

    Я правильно понимаю, что 99% кода приложения скачивается из Сети в виде всяких js-библиотек и без Сети оно не запустится?


    1. Fragster
      27.08.2018 13:37

      Запустится.


  1. CheY
    27.08.2018 13:03

    Приложение зачем-то написано на котлине (а значит тянется рантайм котлина), есть либа для отображения гифок (зачем?), подключены GMS и Firebase, есть детектор тряски… Разумеется оно будет весить много. не понятно, что автор пытался доказать этой статьёй? Сравнить ежа с ужом?


  1. bano-notit
    27.08.2018 19:39

    Мне кажется, что автор статьи явно не понял посыла изначального приложения. Посыл то был «кто сделает тяжелее», а он решил пойти по лёгкому пути и сделать легче…


    1. Siemargl
      27.08.2018 20:06

      Ну страничка хрома то побольше памяти сожрет, даже чем котлиновское ничто =)


  1. dikkini
    27.08.2018 20:34

    Вопрос в другом, а поддерживает ли такой способ написания приложений взаимодействия с железом аппарата? С A-GPS или с GPS? Можно ли для такого приложения реализовать фоновую службу с push уведомлениями? Далеко давно была такая штука, PhoneGAP называлась, она решала вопрос вопрос взаимодействия с HW криво, не полностью и через кучу плагинов.


    1. zv347
      28.08.2018 07:51

      По-видимому, поддерживает, если поддерживает браузер. Это же, по большому счету, браузер в полноэкранном оффлайн-режиме (поправьте, если не прав).
      Поэтому, например, с bluetooth мое PWA-приложение на андроиде работает, а на iOS — пока нет.


  1. Aries_ua
    28.08.2018 10:36

    PWA пока имеет проблемы с Push Notification для iOS. Что очень печалит :(