Progressive web application (PWA) — прогрессивное веб-приложение, это технология для отображение сайта в отдельном приложении. Эту технологию развивает гугл, Apple еще не учитывает всех нюансов.
При запуске со смартфона на android высвечивается запрос на установку приложения в один клик. На рабочем столе появится ярлык для быстрого доступа к сайту, не нужно качать .арк файл, давать дополнительных разрешений. На iOs автоматического запроса нет (пока); установка происходит через — Расшарить — На экран «Домой». К тому же, iOs не всегда подтягивает иконку, название с manifest, кеширует меньше файлов.
Как сделать pwa для сайта
Если вкратце: создаем манифест, service-worker, ставим на сайт.
Manifest.json для pwa
Все файлы в принципе могут называться как угодно, просто так принято. Файл manifest:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | { "short_name": "Bdseo.ru", "name": "Блог вебмастера", "icons": [ { "src":"/images/beach.png", "sizes": "16x16", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "32x32", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "48x48", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "72x72", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "96x96", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "144x144", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "192x192", "type": "image/png" }, { "src":"/images/beach.png", "sizes": "512x512", "type": "image/png" } ], "start_url": "/", "background_color": "#7ACCE5", "theme_color": "#7ACCE5", "orientation": "any", "display": "standalone" } |
short name — название на главном экране;
name — при запуске;
icons — массив с размерами; можно задать больше или меньше разрешений, можно разные иконки прописать;
start_url — какая страница сайта будет открываться;
orientation — можно задать только горизонтальную, вертикальную или в любом положении экрана;
display — standalone, как отдельное приложение, со статус баром. Можно задать еще 3 варианта: Fullscreen (на весь экран, без статус бара), Minimal-UI (будет строка с url и кнопкой Меню как в браузере), Browser (как в браузере).
Остальное цвета. Это не все функции, для примера.
Service-worker файл для pwa
Файл-обработчик самого приложения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | var doCache = true; // Имя кэша var CACHE_NAME = 'pwa-from-bdseo'; // Очищает старый кэш self.addEventListener('activate', event => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys() .then(keyList => Promise.all(keyList.map(key => { if (!cacheWhitelist.includes(key)) { console.log('Deleting cache: ' + key) return caches.delete(key); } })) ) ); }); // 'install' вызывается, как только пользователь впервые открывает PWA self.addEventListener('install', function(event) { if (doCache) { event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { // Получаем данные из манифеста (они кэшируются) fetch('/manifest.json') .then(response => { response.json() }) .then(assets => { // Открываем и кэшируем нужные страницы и файлы const urlsToCache = [ '/app/', '/static/core/logo.svg*', ] cache.addAll(urlsToCache) console.log('cached'); }) }) ); } }); // Когда приложение запущено, сервис-воркер перехватывает запросы и отвечает на них данными из кэша, если они есть self.addEventListener('fetch', function(event) { if (doCache) { event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); } }); |
Задаем путь к manifest.json, кешируем или нет и что кешируем. Внимательно проверяйте пути к файлам.
Установка файлов на сайт для pwa
Дальше задаем путь к файлам на нужных страницах. При использовании движков достаточно задать в header, footer коде.
1 | <link rel="manifest" href="/manifest.json"> |
Путь к файлу manifest, размещаем в заголовке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }).catch(function(err) { console.log(err) }); }); } else { console.log('service worker is not supported'); } </script> |
Скрипт для подключения service-worker. В случае ошибки также выведет информацию в консоль. Лучше размещать в конце страницы, после прогрузки сайта.
Также однотипные файлы/скрипты можно объединять для оптимизации. Например, у вас все js-скрипты в одном файле — подключите и этот. Все json в отдельной папке — положите манифест туда.
В этом примере будет стандартный запрос. Если пользователь отказался, запрашивать какое-то время не будет.
Также можно использовать нестандартную форму запроса, «отлавливать» установил пользователь приложение или нет. Еще высвечивать инструкцию если пользователь зашел с айфона. По нестандартной форме запроса, например через поп-ап окно, я напишу позже.
Ура. Я все смог сделать. У меня теперь PWA в ядре framework. Сначала думал статью про это написать, потом решил что нафига я буду конкурентам рассказывать как это работает. У меня теперь все сайты, которые берут дистрибутив с PWA работают и на рабочий стол добавляются. На Java — это же вообще говнище. Они там теребонькают три месяца чтобы какашку задеплоить в Google Play и делают это с каждым сайтом. Сраное извращение меня не коснулось. Спасибо дружище, но мне пришлось еще 5 манов прочитать. Жду от тебя новых статей.
Всегда пожалуйста. Спасибо за обратную связь.
По ява согласен и нет: парится надо, но когда есть опыт и набитые шишки — все делается красиво и быстро.
У меня даже под беттинг, гемблинг прилы отлично работают, некоторые в маркете.
«Обычные» сайты вообще без проблем. Приложение делаю сейчас за ~20 минут.
Кароче. Install вообще не обязателен как я понял. А у тебя кэш сторадж пустое. Проверь сам. Воркер регистрируется, а кэша в хранилище нету. Мой воркер тоже не работает в том числе и с мобильного устройства. Если выполнить добавление кэша из обычных скриптов — в хранилище появляются записи, но дерьмо в том, что они видимо не возвращаются из кэша. Это говно нельзя использовать — нужно писать APP нормальное без строки URL.
В блоге описал самый простой пример. Если он не работает — напишите (проверял на 2 сайтах)
Вообще, у меня есть 4 или 5 вариантов PWA, с разными способами вызова, кеширования, service-worker, вызов для iOs). Но они для коммерческих проектов.
Кстати, без строки url — нужно сделать Digital Assets Links, описано здесь: https://bdseo.ru/kak-svyazat-android-prilozhenie-i-sajt
Если нужно чтобы и «чужие» сайты показывало без урл — тогда webview.
В общем я сделал немного по другому потому что воркер не кэширует. На каждую загрузку нужно выполнить:
Воркер я сделал вот такой:
Воркер работает фигово. Он должен добавлять ресурсы автоматически но пришлось это сделать кодом выше. Не знаю вообще кэширование возвращается или нет. Lighthouse говорит что оно херовенько работает. Вручную добавлять неинтересно, это будет максимум CSS иконки и шрифты, а все страницы дтнамического сайта можно добавить только при вызовах загрузки, а не из воркера.
И еще нужно учитывать, что максимальный кеш PWA ~50 мбайт
Фиг его знает как оно работает. В кэш я добавление сделал. У меня весь сайт на Fetch запросах. Оно в хранилище кэша есть. Это точно перехаватывает? Я чего-то не смог логирование сделать выброса актуального кэша.
А фиг его знает
Взяли на заметку, спасибо