Maxim Salnikov
@webmaxru
Как сделать веб-приложение прогрессивным
@webmaxru
Full-stack разработчик "приложений из будущего" в ForgeRock
Эти приложения запускаются везде и обладают рядом характеристик, обеспечивающих пользователей преимуществами, аналогичными тем, что доступны в нативных решениях.
За флагом
OS
Service Worker API
Web App Manifest
SW библиотека
Включено
Настройка
Расширение
Web App Manifest
App Shell
Runtime Caching
Push Notifications
Update Flow
$ ng add @angular/pwa
SW библиотека
Включено
Настройка
Расширение
Web App Manifest
App Shell
Runtime Caching
$ vue add @vue/pwa
SW библиотека
Включено
Настройка
Расширение
create-react-app my-react-pwa
Web App Manifest
App Shell
Runtime Caching
My App
Доступна новая версия.
Обновить?
# Installing the Workbox Node module
$ npm install workbox-build --save-dev
// We will use injectManifest mode
const {injectManifest} = require('workbox-build')
// Sample configuration with the basic options
var workboxConfig = {...}
// Calling the method and output the result
injectManifest(workboxConfig).then(({count, size}) => {
console.log(`Generated ${workboxConfig.swDest},
which will precache ${count} files, ${size} bytes.`)
})
[
{
"url": "index.html",
"revision": "34c45cdf166d266929f6b532a8e3869e"
},
{
"url": "favicon.ico",
"revision": "b9aa7c338693424aae99599bec875b5f"
},
...
]
// Sample configuration with the basic options
var workboxConfig = {
globDirectory: 'dist/angular-pwa/',
globPatterns: [
'**/*.{txt,png,ico,html,js,json,css}'
],
swSrc: 'src/service-worker.js',
swDest: 'dist/angular-pwa/service-worker.js'
}
// Importing Workbox itself from Google CDN
importScripts('https://googleapis.com/workbox-sw.js');
// Precaching and setting up the routing
workbox.precaching.precacheAndRoute([])
{
"scripts": {
"build-prod": "ng build --prod &&
node workbox-build-inject.js"
}
}
Файлы приложения
Список файлов для app shell
Файл сервис-воркера
Через хеш-суммы
Через вставку
// App shell
workbox.precaching.precacheAndRoute([])
// Runtime caching
workbox.routing.registerRoute(
/(http[s]?:\/\/)?([^\/\s]+\/)api/,
workbox.strategies.networkFirst()
)
// Push notifications
self.addEventListener('push', (event) => {...})
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/service-worker.js')
}
Доступна новая версия приложения. Перезагрузить страницу?
import { register } from 'register-service-worker'
platformBrowserDynamic().bootstrapModule(AppModule)
.then( () => {
register('/service-worker.js')
})
$ npm install register-service-worker --save
register('/service-worker.js', {
})
updated (registration) {
if (confirm(`New content is available!
Click OK to refresh`)) {
window.location.reload();
}
}
Cache-Control: max-age=0
self.addEventListener('install', (e) => {
self.skipWaiting();
});
self.addEventListener('activate', (e) => {
self.registration.unregister()
.then(() => {
return self.clients.matchAll();
})
.then((clients) => {
clients.forEach((client) => client.navigate(client.url));
});
});
Maxim Salnikov
@webmaxru