New Features
https://sajeetharan.com | @kokkisajee
University of Ruhuna | 29/06/2019
I'm Sajeetharan Sinnathurai
@kokkisajee
ng-Hello!
In a nutshell
Communities
Social Developer
Recognitions
Watch his bowling vs England
1995 JS creation
1997 ECMA standard
2007 V8 project starts
2008 - 2010 Race for speed
2009 AngularJS
2013 React
2009 NodeJS
2014 VueJS
2018 > 5B devices
Here's a story
Traditional Website
Request
Client requests website via URL.
Server responds with HTML document. This includes CSS and JavaScript links.
Mobile App
Request
Mobile app already includes layout files, requests data from server.
Server responds with data (JSON). Mobile app populates local layout with returned data.
A mixture of native and web technologies
Write app using JavaScript
Wrap in a native container, deliver through app stores
'Feels' like a native app, but code can be reused across platforms
Regular web pages, designed for small screens
Accessed through web browser on any device
Access to some hardware sensors (geolocation, accelerometer)
Will never be as performant as native apps
No App Store presence
Games, highly customised designs: native will be the most perfomant.
Simple web presence, runs on a broad range of devices, don't care about app stores: mobile web.
Otherwise: Many apps will benefit from a hybrid approach.
"PWAs are the missing technology link to bring the best features of the web to solve the issues of native apps and closed marketplaces"
Chris Heilmann
76% more conversions between browsers
14% more active users/month on iOS; 30% more in Android
4X more rate of action from "Add to Homescreen"
App
Service worker
AJAX
Static
Dynamic
RWD
PWA
Download
https://nodejs.org/en/download/
https://code.visualstudio.com/
Install
Run!
npm install -g @angular/cli@next
ng new ngHero --routing --style=scss
cd ngHero
npm start
1. Your website should be HTTPS enabled
2. Your website should be responsive
Service Worker
Client
Server
$ ng new myPWA
$ ng add @angular/pwa --project=myPWA
$ ng build --prod
npm install -g http-server@0.9.0
http-server -p 8080
NGSW Debug Info:
Driver state: NORMAL ((nominal))
Latest manifest hash: cd4716ff2d3e24f4292010c929ff429d9eeead73
Last update check: 9s215u
=== Version 34c3fd2361735b1330a23c32880640febd059305 ===
Clients: 7eb10c76-d9ed-493a-be12-93f305394a77
=== Version cd4716ff2d3e24f4292010c929ff429d9eeead73 ===
Clients: ee22d69e-37f1-439d-acd3-4f1f366ec8e1
=== Idle Task Queue ===
Last update tick: 4s602u
Last update run: 9s222u
Task queue:
Debug log:
$ ng set apps.0.serviceWorker=true
$ npm install @angular/service-worker --save
{
"index": "/index.html",
"assetGroups": [...],
"dataGroups": [...]
}
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
...
@NgModule({
...
imports: [
...
]
})
export class AppModule { }
ServiceWorkerModule.register('/ngsw-worker.js',
{ enabled: environment.production }),
{
"index": "/index.html",
"assetGroups": [...],
"dataGroups": [...]
}
{
"name": "app",
"installMode": "prefetch",
"resources": {...}
}
"resources": {
}
"versionedFiles": [
"/*.bundle.css",
"/*.bundle.js",
"/*.chunk.js"
],
"files": [
"/favicon.ico",
"/index.html"
],
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {...}
}
"resources": {
}
"files": [
"/assets/**"
],
"urls": [
"https://fonts.googleapis.com/**",
"https://fonts.gstatic.com/**"
]
{
"name": "api-freshness",
"urls": [
"/api/breakingnews/**"
],
}
"cacheConfig": {
"strategy": "freshness",
"maxSize": 10,
"maxAge": "12h",
"timeout": "10s"
}
{
"name": "api-performance",
"urls": [
"/api/archive/**"
],
}
"cacheConfig": {
"strategy": "performance",
"maxSize": 100,
"maxAge": "365d"
}
{
"version": 1,
"name": "api-performance",
"urls": [
"/api/**"
],
...
}
{
"version": 2,
"name": "api-performance",
"urls": [
"/api/**"
],
...
}
import { SwUpdate } from '@angular/service-worker';
constructor(private swUpdate: SwUpdate) {}
this.swUpdate.available.subscribe(event => {
let snackBarRef = this.snackBar
.open('Newer version of the app is available', 'Refresh');
snackBarRef.onAction().subscribe(() => {
window.location.reload()
})
})
import { SwPush } from '@angular/service-worker';
constructor(private swPush: SwPush) {}
subscribeToPush() {
this.swPush.requestSubscription({
serverPublicKey: this.VAPID_PUBLIC_KEY
})
.then(pushSubscription => {
// Pass subscription object to backend
})
}
{
"notification": {
}
}
"title": "Very important notification",
"body": "Angular Service Worker is cool!",
"icon": "https://angular.io/assets/logo.png",
"actions": [
{
"action": "gocheck",
"title": "Go and check"
}
],
...
Hope things go smoothly
Otherwise
Where to go from here?
- Build Apps
- Send your queries @kokkisajee
- Be a part of Ng-SriLanka
- Demo code