Anatomy of a
Progressive Web App
January 20, 2017
Michael North
Agent Conf
2007
A lot has changed since 2012
Benefits of Each
Approach
WebNative
• Presence on home screen
• Background functionality
• Fast return startup
• Doesn’t require install
• Cross-Platform
• Very similar to desktop web experience
Vs
Progressive Web Apps
Hello!
Formerly Now
• CTO
• UI Architect @
• Lead Engineer @ Imagequix
• Training Partner @
• Staff Engineer @
• Instructor @
Major Pieces
Pruning the Critical Path
Tolerating Network Instability
App-Like Characteristics
Important Metrics
Pruning the Critical Path
🎨First Paint
👆Interactive
Time to…
📊Data
index.html
app.css
app.js
data.json
API
🖥User
Asset Storage
1
2
4
5
6
Static Hosting
3
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆 📊
Client
Rendered
SPA
Server-Side Rendering
• ⏱ Don’t have to wait for client-side JS
• 🔗 Better for SEO & sharing links
• ⚠ Node.js and the Browser are different
• 👷 Try not to do the same work twice
• ⚡ HTML is assembled in your data center
index.html
app.css
app.js
data.json
API
🖥User
Asset Storage
1
2
6
7
8
Rendering
Server
5
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆📊
Server
Rendered
SPA
3
4
Resource Caching Strategies
• Content at a URL is never
changed
• max-age=year
• index.html is the key
• Offline-friendly
• Content at a URL can change
• Cache-Control: no-cache
• Use Last-Modified or ETag
• Involves extra network
requests
Immutable Content “Check w/ server”
Service Workers
• A programmable network proxy
• A JavaScript worker
• Only works over HTTPS
• Has a predictable lifecycle
XHR SW WWW
Cache
Service Workers
Installing
Activated Error
Idle
FetchTerminated
Service Workers
I need item.pngApp
Of course! Here it is.
I have a list of important
resources. I’ll fetch them
all and cache them.
Cache
Precache
🖼
Service Workers
App
Just got it for you!
Ok, I’ll get it
Cache
Network or Cache
🖼
I need item.png
Service Workers
Took too long. Here’s a
cached version🖼
App
Ok, I’ll get it
Cache
Network or Cache
I need item.png
Service Workers
App
Ok, I’ll get it
Cache
Network or Cache
I need item.png
Something went wrong.
Here’s a cached version🖼
Service Workers
App
I’ll go download a new
copy in case it changed
Here’s a cached version
Cache
Cache and Update
🖼
I need item.png
Next time you ask, you’ll
get this new version
Service Workers
App
I’ll go download a new
copy in case it changed
Here’s a cached version
Cache
Cache, Update and Refresh
🖼
I need item.png
Hey! I’ve got a new
version. Ask me for itpostMessage
🎆
Service Workers
index.html
app.css
app.js
data.json
API
🖥User
Asset Storage
1
2
6
7
8
Rendering
Server
5
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆📊
Server
Rendered
SPA
3
4
index.html
.css
.js data.json
API
🖥User
Asset Storage
1
2
6
7
8
Rendering
Server
5
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆📊
Server
Rendered
PWA v1
3
4
Service
Worker
⚙
Storing Dynamic Content
• Cookies - Not worker-friendly, just a string
• LocalStorage - See 👆
• What’s left???
Storing Dynamic Content
• Cookies - Not worker-friendly, just a string
• LocalStorage - See 👆
IndexedDB
IndexedDB
• 🔢 Versioned
• 🗃 Indexable
• ⚙ Worker-Friendly
• 📅 Durable
• 🔣 Supports values of many types
• ⚠ Not a SQL, or a relational DB
IndexedDB
!// Open (or create) the database
let open =
indexedDB.open('MyDatabase', 1);
!// Create and/or Migrate the Schema
open.onupgradeneeded = (evt) !=> {
!// Transactions
open.onsuccess = () !=> {
!!... };
!!... };
IndexedDB
!// Create and/or Migrate the Schema
open.onupgradeneeded = (evt) !=> {
};
let db = open.result;
let store = null;
switch (evt.oldVersion) {
case 0: !// Upgrade from 0
!// !!...
case 1: !// Upgrade from 1
!// !!...
}
IndexedDB
!// Open (or create) the database
let open =
indexedDB.open('MyDatabase', 1);
!// Create and/or Migrate the Schema
open.onupgradeneeded = (evt) !=> {
!// Transactions
open.onsuccess = () !=> {
!!... };
!!... };
IndexedDB
App Shell Architecture
Shell loads instantly Dynamic content in the shell
index.html
.css
.js data.json
API
🖥User
Asset Storage
1
2
6
7
8
Rendering
Server
5
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆📊
Server
Rendered
PWA v1
3
4
Service
Worker
⚙
index.html
.css
.js data.json
API
🖥User
Asset Storage
1
2
6
7
8
Rendering
Server
5
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆📊
Server
Rendered
PWA v2
3
4
Service
Worker
⚙
99
shell html
First Visit
💾
IndexedDB
99
Records
LocalRem
ote
shell.html
.css
.js
IndexedDB
API
🖥User
Asset Storage
4
7
8
Rendering
Server
3
☁CDN
🎨
First Paint
👆
Interactive
parse
📊
Data
🎨
boot
👆 📊
Server
Rendered
PWA v2
Service
Worker
⚙
Return Visit
2
1
💾
IndexedDB
5
6
data.json
Major Pieces
Pruning the Critical Path
Tolerating Network Instability
App-Like Characteristics
✅
✅
App-Like Characteristics
App-Like Characteristics
<meta name="apple-mobile-web-app-capable" content="yes">
Get rid of browser UI
App Icons
<link sizes=“180x180" rel=“apple-touch-icon" href="icon.png">
<meta name="mobile-web-app-title" content="Mike.Works">
Bookmark Name
<link href="splash.png" rel="apple-touch-startup-image">
Splash Screen
App-Like Characteristics
{
"name": "Mike.Works - World Class Developer Training",
"short_name": "Mike.Works",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"theme_color": "#fff",
"description": "World Class Developer Training",
"orientation": "portrait-primary",
"lang": "en-US",
"icons": [ ]
};
manifest.json
App-Like Characteristics
In The Future…
• 💬 Push Notifications
• 🔁 Background Sync
• ⚛ First-Class Framework Support
• 📦 IndexedDB 2.0
• ⚡ HTTP/2 Optimizations
This is getting very
complicated…
Reduce the # of
decisions you must make
🤔
You will be building
these things…
Get Trained.
Get Trained.
https://mike.works

Anatomy of a Progressive Web App