@QCon Shanghai Oct 2016
huangxuan.me / Weibo / GitHub / 知乎
export default () => (
<Huxpro zh='黄玄' en='Hux'>
<Wepiao from="2015" team="Frontend Infrastructure" />
<Taobao from="2014" team="AliTrip - Mobile Web" />
</Huxpro>
)
Easy Discovery
Linkable
Cross Platform
Broad Reach
Performant
Intergration
Low Friction
Seamless Release
Easy Discovery
Linkable
Cross Platform
Broad Reach
Performant
Intergration
Low Friction
Seamless Release
Low capability
High capability
Device Access
Media/Geolocation/Gesture/Accelerometer/etc.
OS Intergration
HCI/HomeScreen/Push Notification/FileSystem/
Background Threads/etc.
UI Performance
DOM & Retained Mode/GPU Rasterization
Network
Latency/Cache/Offline/Network Resilience
WIRED: The Web Is Dead. Long Live the Internet (2010)
WSJ: The Web Is Dying; Apps Are Killing It (2013)
TC: As Mobile Roars Ahead, It’s Time To Finally Admit The Web Is Dying (2014)
TheVerge: The mobile web sucks (2015)
Living With Web Apps: the 10 deadly sins of a mobile web app (2015)
Mobile JavaScript Apps: The Problem with the Mobile Web (2016)
Low capability
High capability
Device Access
Media/Geolocation/Gesture/Accelerometer/etc.
OS Intergration
HCI/HomeScreen/Push Notification/FileSystem/
Background Threads/etc.
UI Performance (We can make it!)
DOM & Retained Mode/GPU Rasterization
Network
Latency/Cache/Offline/Network Resilience
✓
✓
✓
✓
Nobody, maybe me
Nobody, maybe me
2008-01-15
Added section on specifying a web clip icon.
2008-09-09
Bookmarked home screen apps open in full screen
<!-- Add to homescreen for Chrome on Android -->
<meta name="mobile-web-app-capable" content="yes">
<mate name="theme-color" content="#000000">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Lighten">
<!-- Tile icon for Win8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
<meta name="msapplication-TileColor" content="#3372DF">
<!-- iOS icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="images/touch/apple-touch-icon-144x144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="images/touch/apple-touch-icon-114x114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="images/touch/apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="images/touch/apple-touch-icon-57x57-precomposed.png">
<!-- Generic Icon -->
<link rel="shortcut icon" href="images/touch/touch-icon-57x57.png">
<!-- Chrome Add to Homescreen -->
<link rel="shortcut icon" sizes="196x196" href="images/touch/touch-icon-196x196.png">
The "Good Old Time"
{
"short_name": "Manifest Sample",
"name": "Web Application Manifest Sample",
"icons": [{
"src": "launcher-icon-2x.png",
"sizes": "96x96",
"type": "image/png"
}],
"background_color": "#fff",
"theme_color": "#000",
"start_url": "/index.html",
"display": "standalone",
"orientation": "landscape"
}
<link rel="manifest" href="/manifest.json">
(Offline Web App Spec)
<html manifest="cache.appcache">
In private session ;)
// register Service Worker in index.html
if('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw.js')
.then( registration => {
console.log('Service Worker Registered');
}).catch( error => {
console.log('Registration failed with' + error);
})
}
Let's Build An AirHornor
// sw.js
self.addEventListener('install', e => {
e.waitUntil(
caches.open('airhorner').then(cache => {
return cache.addAll([
'/',
'/index.html',
'/index.html?homescreen=1',
'/?homescreen=1',
'/styles/main.css',
'/scripts/main.min.js',
'/sounds/airhorn.mp3'
])
.then(() => self.skipWaiting());
})
)
});
You manage what is 'installed' and how it's cached
// WEBIDL
interface ExtendableEvent : Event {
void waitUntil(Promise<any> f);
};
// WEBIDL
interface ServiceWorkerRegistration : EventTarget {
readonly attribute ServiceWorker? installing;
readonly attribute ServiceWorker? waiting;
readonly attribute ServiceWorker? active;
}
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
self.onfetch = (e) => {
const cached = caches.match(e.request)
const fallback = caches.match('offline.html')
const fetched = fetch(`${e.request.url}?${Date.now()}`)
const fetchedCopy = fetched.then(_ => _.clone())
e.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => fallback)
)
e.waitUntil(
Promise.all([fetchedCopy, caches.open('runtime')])
.then(([resp, cache]) => resp.ok && cache.put(e.request, resp))
.catch(_ => {/* swallow */})
)
}
The First Service Worker
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
Updating the Service Worker
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
// sw.js
self.addEventListener('activate', function(event) {
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.filter(function(cacheName) {
// Return true if you want to remove this cache,
// but remember that caches are shared across
// the whole origin
}).map(function(cacheName) {
return caches.delete(cacheName);
})
);
})
);
});
Clean-up & Migration.
(SW can be built as progressive enhancement In.)
Service Worker
Cache
Fetch
Push
Notification
Sync
Promise
HTTPS
HTTP2.0
Web Payment
Device API
Web Socket
Web Push Protocol
Indexed DB
ExtendableEvent
Web Workers
RWD
ES2015
Stream
(without bypassing GFW)
Work Offline Caching Push Notification
"Hey I saw the URL bar, This is a website!"
"This is an offline
reliable app!"
←
"Hey I saw the URL bar, This is a website!"
"This is a bookmark!"
←
"I aware of it."
"I can install App from Browser(URL)!"
"This is an offline
reliable app!"
←
Low capability
High capability
Low capability
High capability
Nobody, maybe me, reply to the "Web as Adaptive Platform"
huangxuan.me / Weibo / GitHub / 知乎
自豪的采用 @演说.io
huangxuan.me / Weibo / GitHub / 知乎