иллюстрация к статье PWA

 

РАЗРАБОТКА PWA (Progressive Web Applications)

PWA (Progressive Web Applications)  - веб-сайт с возможностью установки на устройство пользователя и использования в виде нативного приложения в дальнейшем. 

На самом деле общего и точного определения у PWA нет, но для обычного пользователя все сводится к двум показателям: возможность установить PWA на мобильное устройство и использование веб-ресурса offline. Основная задача PWA - позволить работать с веб-сайтом как с “нативным” приложением на любом устройстве. 

PWA-технология предоставляет отдельный слой логики для веб-сайта, которая по своей сути является “оберткой”. Данная особенность означает, что мы не ограничены в выборе инструментов для разработки приложения. Однако, есть базовые ограничения для использования всех возможностей PWA-технологии:

  1. Браузеры Chrome или Safari.
    На данный момент PWA-технология полностью поддерживается браузерами Chrome и Safari. Начиная с версии 16.4 Safari стал поддерживать push-уведомления. 
  2. HTTPS-протокол ресурса PWA.
    Для полноценной работы как PWA-технологии, так и большинства браузерных API требуется HTTPS-протокол. При запуске на HTTP у приложения не будет возможности установки и использования ServiceWorker.
  3. Зарегистрированный ServiceWorker (SW) и файл manifest.json.
    То, что делает наш сайт именно PWA-приложением:
  • SW является событийно-управляемым “воркером”, который работает в потоке отдельном от основного потока JavaScript на странице, обеспечивает установку приложения на устройство, работу приложения в оффлайн, стратегии кэширования и многое другое. 
  • Файл manifest.json содержит в себе настройки для предоставления нативных функций PWA-приложению.

Жизненный цикл ServiceWorker

  1. Регистрация SW. Проверяем наличие API ServiceWorker в браузере и вызываем метод регистрации в точке входа в приложение (/public/index.html) или корневом файле (/src/index.jsx).
  2. Событие Install. Срабатывает сразу после регистрации. При обработке события доступно взаимодействие с кэшем ServiceWorker и отслеживание события update - наличия новых обновлений приложения.
  3. Событие Activate. ServiceWorker установлен, при обработке события можно удалить старый кэш.
  4. Режим idle. После установки ServiceWorker переходит в “спящий режим” до момента следующего вызова.
  5. Событие fetch. Срабатывает при каждом API-запросе. Для кэширования ответов и использования данных offline необходимо указание настроек для стратегии кэширования в приложении.

Стратегии кэширования данных для ServiceWorker

  1. “Cache first”. 
  • Суть: API-запрос направляется в кэш, при отсутствии ответа - в сеть.
  • Применение: подходит для ресурсов, которые редко изменяются (лого, шрифты).
  1. “Network first”. 
  • Суть: сначала делается API-запрос к сети, если сеть недоступна - проверяется кэш.
  • Применение: подходит для часто меняющегося контента (данные пользователя).
  1. “Cashe only”. 
  • Суть: все API-запросы направляются в кэш, если ресурса нет, то он не будет загружен.
  • Применение: подходит для приложений со статикой (landing).
  1. “Network only”. 
  • Суть: все API-запросы направляются в сеть, кэш игнорируется.
  • Применение: подходит для данных, которые всегда должны быть актуальными (банковские данные).
  1. “Stale-While-Revalidate”. 
  • Суть: сначала проверяется кэш и возвращается кэшированный ресурс (если доступен), одновременно отправляется API-запрос для обновления кэша.
  • Применение: подходит для загрузки и обновления изображений.

Разработка приложения

При старте нового проекта лучше всего использовать готовые шаблоны (Vite - vite-pwa-plugin, Webpack - cra-template-pwa и т.д.), которые серьезно облегчат взаимодействие с SW и его настройку. 

Наиболее распространенной стратегией кэширования является Network first, которая по своей сути и отражает основное назначение SW: предоставить возможность пользователю взаимодействовать с приложением оффлайн при отсутствии доступа к сети. При отсутствии настроек по стратегии кэширования в приложении базовые ресурсы (JavaScript, CSS, HTML) будут предварительно кэшироваться во время установки SW, пользователь сможет использовать приложение offline, но только с теми архивными ресурсами, которые были предварительно кэшированы.

Процесс разработки 

Вариант для Vite + vite-pwa-plugin + ReactJS

  1. Создаем новое приложение по шаблону от Vite при помощи команды: npm create vite@latest 
  2. Разрабатываем MVP-версию приложения приложения на ReactJS.
    Процесс разработки самих интерфейсов PWA-приложения ничем не отличается от разработки обычного веб-сайта, но зачастую требует наличия адаптивной верстки и дизайна для мобильных устройств.
  3. Устанавливаем плагин для генерации PWA-assets при помощи команды:
    npm i @vite-pwa/assets-generator -D 
    Настраиваем конфигурацию плагина vite-pwa-plugin в файле vite.config.js либо vite.config.ts 

(ссылка на источник):

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
 plugins: [
   react(),
   VitePWA({
     injectRegister: 'auto',
     registerType: 'autoUpdate',
     includeAssets: ["favicon.ico", "apple-touch-icon.png", "mask-icon.svg"],
     manifest: {
       name: "My Awesome App",
       short_name: "MyApp",
       description: "My Awesome App description",
       theme_color: "#ffffff",
       icons: [
         {
           src: "pwa-192x192.png",
           sizes: "192x192",
           type: "image/png",
         },
         {
           src: "pwa-512x512.png",
           sizes: "512x512",
           type: "image/png",
         },
       ],
     },
   }),
 ],
}); 
  1. Указываем настройки для стратегии кэширования в приложении по стратегии Network first:
export default defineConfig({
 plugins: [
   react(),
   VitePWA({
     ...other settings,
     workbox: {
       runtimeCaching: [
         {
           urlPattern: /^https:\/\/test-api-domain\.com\/.*$/, 
           handler: 'NetworkFirst',
           options: {
             cacheName: 'api-cache',
             networkTimeoutSeconds: 10,
             expiration: {
               maxEntries: 50,
               maxAgeSeconds: 5 * 60,
             },             
           }
         },
       ],
     }
   }),
 ],
});

 

  1.  urlPattern - регулярное выражение для определения шаблона URL, для которого будет применена стратегия кэширования. В данном примере это любые API-запросы, содержащие в адресе строку “https://test-api-domain.com/”.
  • handler - задает стратегию кэширования. В данном случае 'NetworkFirst'.
  • options.cacheName - имя кэша, который будет использоваться для хранения ответов.
  • options.networkTimeoutSeconds - таймаут для сетевого запроса в секундах.
  • options.expiration.maxEntries - максимальное количество записей, которые можно сохранить в кэше.
  • options.expiration.maxAgeSeconds - максимальное время хранения в секундах для записей.
  1. Добавляем новый скрипт в package.json для создания PWA-assets (ссылка на источник): "generate-pwa-assets": "pwa-assets-generator --preset minimal public/logo.svg"
  2. Добавляем исходный svg-файл с логотипом приложения (public/logo.svg) и запускаем скрипт для создания PWA-assets: npm run generate-pwa-assets

Указываем код в index.html для использования PWA-assets (ссылка на источник):

<head>
 ...other code
 <meta name="viewport" content="width=device-width,initial-scale=1">
 <title>My Awesome App</title>
 <meta name="description" content="My Awesome App description">
 <link rel="icon" href="/favicon.ico">
 <link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
 <link rel="mask-icon" href="/mask-icon.svg" color="#FFFFFF">
 <meta name="theme-color" content="#ffffff">
</head> 
  1. Запускаем команды в консоли:
npm run build
npm run preview
  1. Проверяем приложение:
  • Браузер → инструменты разработчика → Application → Service Workers → на вкладке должна быть указана информация о SW приложения.
  • В крайнем правом углу должна появиться кнопка с возможностью установить приложение на устройство.
  • Тестирование стратегии кэширования:
  1. Взаимодействуем с приложением для отправки нескольких API-запросов по адресу, указанному в настройках стартегии кэширования.
  2. Ответы успешных запросов будут сохранены в кэш SW.
  3. В инструментах разработчика отключаем сеть.
  4. Переходим на страницы, с которых отправлялись запросы: данные должны быть отображены в режиме offline.

Данный вариант позволяет быстро развернуть стандартное PWA-приложение, а также преобразовать в PWA-приложение уже существующий веб-ресурс при условии, что изначально использовался сборщик Vite.

Нет времени на разработку? 

НАЖМИТЕ, И МЫ ВСЕ СДЕЛАЕМ!

 

Конвертация PWA-приложения в APK файл

ОС Android
Для данной ОС возможна конвертация PWA-приложения в apk файл, с его последующей установкой на устройстве:

  1. Переходим на сайт
  2. указываем веб-адрес PWA-приложения, жмем Start
  3. по результатам сканирования могут быть выявлены критические недостатки, которые не позволяют сервису собрать сборку
  4. устраняем недостатки, деплоим, повторяем предыдущие действия
  5. если сканирование успешно, в верхнем правом углу будет активна кнопка Package for stores → жмем, выбираем Generate package на карточке Android
  6. будет загружен архив, из архива нам нужен сам .apk-файл
  7. загружаем файл на Android-устройство и устанавливаем
  • Локально при помощи Bubblewrap + Gruddle + Java Development Kit
  1. выполняем команду в консоли: 
    npm install -g @bubblewrap/cli
  2. переходим в директорию PWA-приложения, выполняем команду:
    bubblewrap init --manifest https://test.pwa/manifest.json (адрес заменить на URL-адрес Web App Manifest файла)
  3. в ходе инициализации скачиваем недостающие пакеты, указываем требуемые настройки. 
  4. выполняем в консоли команду:
    bubblewrap build
  5. проверяем наличие .apk-файла в нашем проекте