in the #YearOfPWA
Maxim Salnikov
@webmaxru
Progressive
Angular Apps
How to create Angular Progressive Web App?
Using the native tools
Maxim Salnikov
-
Google Developer Expert, Microsoft MVP
-
Angular Oslo / PWA Oslo meetups organizer
-
ngVikings conference organizer
-
ngCommunity maintainer
Products from the future
UI Engineer at ForgeRock
After all, what is PWA?
Progressive web apps use modern web APIs along with traditional progressive enhancement strategy to create cross-platform web applications.
These apps work everywhere and provide several features that give them the same user experience advantages as native apps.
Cross-platform?
Browser
Desktop
Mobile
Flagged
OS
#YearOfPWA
UX advantages?
Smart networking + Offline
Proper app experience
Staying notified
Other cool things
}
Service Worker API
Web App Manifest
❤
Service worker options
-
Code service worker manually
-
Use framework-agnostic PWA libraries
-
Use Angular Service Worker
NGSW
Automate it!
Automation
-
Scaffolding
-
Building
-
Running
1
2
3
Schematics
Angular CLI
NGSW
PWA MVP
Recipe #1
Minimal PWA
-
Served via HTTPS
-
Responsive, fast, cross-browser
-
App metadata provided
-
App loads while offline
$ ng add @angular/pwa
Apply PWA schematics
1
-
Add service worker registration code to the root module
-
Generate default service worker configuration file
-
Generate and link default Web App Manifest
-
Generate default icons set
-
Enable build support in Angular CLI config
$ ng build --prod
Build
ngsw-worker.js
ngsw.json
dist/project-name
safety-worker.js
assets/icons/*.png
manifest.json
worker-basic.min.js
2
Running and auditing
$ ng serve
Static dev webserver
-
serve
-
superstatic
-
lite-server
$ ng serve --prod
Dev Tools / Audit / PWA
Automated app shell actions
-
Generate assets (+ hashes) list
2
3
-
Load and cache assets
-
Set up routing
-
Serve assets from the Cache Storage
-
Load and cache the updated assets
-
Inform the application about the update (next recipe)
NGSW configuration file
ngsw-config.json
{
"index": "/index.html",
"assetGroups": [...],
"dataGroups": [...]
}
App shell
assetGroups
{
"name": "app",
"installMode": "prefetch",
"resources": {...}
}
App shell resources
assetGroups / "app" / resources
"resources": {
}
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js"
]
Hint: Automate server-side rendering
Angular Universal PWA Kit
$ ng add @ng-toolkit/universal
Run before adding @angular/pwa
Important!
src/
assets/icons/*.png
manifest.json
index.html / <meta name="theme-color" ...>
To be customized
App update notification
Recipe #2
App version updates
v1
v2
v1
v1
v2
Server
Browser
v2
Using SwUpdate service
import { SwUpdate } from '@angular/service-worker';
constructor(updates: SwUpdate) {}
this.updates.available.subscribe(event => {
})
updates.component.ts
if (confirm(`New Version is available! OK to refresh`)) {
window.location.reload();
}
Hint: Provide a version description
{
"appData": {
"versionMessage": "New version: Push notifications added!"
},
...
}
let appData = event.available.appData
let versionMessage = appData ? appData['versionMessage']
: 'New version is available!'
ngsw-config.json
updates.component.ts
Adding more resources to the App Shell
Recipe #3
App shell / on-demand
assetGroups
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {...}
}
App shell / on-demand
assetGroups / "assets" / resources
"resources": {
}
"files": [
"/assets/**"
],
"urls": [
"https://fonts.googleapis.com/**",
"https://fonts.gstatic.com/**"
]
Removing routes from NGSW control
Recipe #4
ngsw-config.json
"navigationUrls": [
'/**',
'!/**/*.*',
'!/**/*__*',
'!/**/*__*/**',
]
'!/**/login*',
'!/**/account*'
What to redirect to index.html
Data requests caching
Recipe #5
Runtime caching
dataGroups
{
"name": "api-freshness",
"urls": [
"/api/breakingnews/**"
],
}
"cacheConfig": {
"strategy": "freshness",
"maxSize": 10,
"maxAge": "12h",
"timeout": "10s"
}
Runtime caching
dataGroups
{
"name": "api-performance",
"urls": [
"/api/archive/**"
],
}
"cacheConfig": {
"strategy": "performance",
"maxSize": 100,
"maxAge": "365d"
}
Hint: Support API versioning
dataGroups
{
"version": 1,
"name": "api-performance",
"urls": [
"/api/**"
],
...
}
{
"version": 2,
"name": "api-performance",
"urls": [
"/api/**"
],
...
}
Subscribing for the Push notifications
Recipe #6
Push notifications
import { SwPush } from '@angular/service-worker';
constructor(push: SwPush) {}
subscribeToPush() {
this.push.requestSubscription({
serverPublicKey: this.VAPID_PUBLIC_KEY
})
.then(pushSubscription => {
// Pass subscription object to the backend
})
}
push.component.ts
Push notifications / send
{
"notification": {
}
}
server-side.js / sendNotification payload
"title": "Very important notification",
"body": "Angular Service Worker is cool!",
"icon": "https://angular.io/assets/logo.png",
"actions": [
{
"action": "gocheck",
"title": "Go and check"
}
],
...
In case of emergency
Recipe #7
Last resort
cp safety-worker.js ngsw-worker.js
self.addEventListener('install', e => { self.skipWaiting(); });
self.addEventListener('activate', e => {
e.waitUntil(self.clients.claim());
self.registration.unregister().then(
() => { console.log('Unregistered old service worker'); });
});
safety-worker.js
A gentle way
rm ngsw.json
Disadvantages
-
Angular Service Worker always works as the main service worker of the whole application
-
There is no [documented] way to extend the functionality
Advantages
-
Minimal PWA goes out-of-the-box
-
Essential features are codeless
-
Doing things in Angular way
-
Advanced integrity checks + fallback support
-
1700+ developers
-
Major browsers/frameworks/libs reps
Thank you!
Maxim Salnikov
@webmaxru
Questions?
Progressive Angular Apps in the #YearOfPWA
By Maxim Salnikov
Progressive Angular Apps in the #YearOfPWA
Many web developers agree in opinion that 2018 will open a new milestone for the web. This will be a year of the really broad adoption of progressive web apps by all the parties: browser vendors, developers, users. What does Angular team contribute to this movement? Let’s have a deep look at the latest and greatest Angular Service Worker. We skip the documentation-like feature listing and look beyond: practical applications, current browsers support, known limitations and lots of useful insights and tips & tricks. Example of server-side rendered and cached application shell is included! As a practical outcome of the session, you will know how to create a truly progressive Angular app, while saving time and nerves by avoiding some deep pitfalls waiting for you in seemingly simple (but quite tricky when in comes to the real world use cases) PWA idea.
- 1,493