Progressive Web Apps

Make Web Great Again (复兴序章)

@QCon Shanghai Oct 2016

"It's a trap!!"

export default () => (
  <Huxpro zh='黄玄' en='Hux'>
    <Wepiao from="2015" team="Frontend Infrastructure" />
    <Taobao from="2014" team="AliTrip - Mobile Web" />
  </Huxpro>
)

Progressive Web App?

Let's first talk about 

The State Of Web

WE WON ON DESKTOP!

"The Strength of (Desktop) Web"

Easy Discovery

Linkable

URL

Cross Platform

Broad Reach

Performant

Intergration

Low Friction

Seamless Release

Open

Capable

On-Demand

"...JUST IN TIME

FOR MOBILE TO

EAT THE WORLD"

"WE HAVE HTML5!"

"DON'T WORRIED"

"New open standards created in the mobile era, such as HTML5, will win on mobile devices." (2010)

"The Fact of Mobile Web"

"Web On Mobile"

Easy Discovery

Linkable

URL

Cross Platform

Broad Reach

Performant

Intergration

Low Friction

Seamless Release

Open

Capable

On-Demand

Web

Native

Low capability

High capability

Performance
Intergration

Lacking...

Device Access 

Media/Geolocation/Gesture/Accelerometer/etc.

OS Intergration

HCI/HomeScreen/Push Notification/FileSystem/

Background Threads/etc. 

Network 

Latency/Cache/Offline/Network Resilience

"I think the biggest

mistake that we made,

as a company, is betting too much on HTML5 as opposed to native ." (2012)

😩

"Reversals happen frequently when we see changes in form factor"

"Is writing JavaScript and HTML a dead-end thing to do?"

Community Stick On Web and Push...

Web Technologies

"we feel the web as a platform is at a disadvantage, and we’re working to polyfill those gaps with PhoneGap." (2008)

Web

Native

Low capability

High capability

Performance
Intergration

Hybrid

Device Access 

Media/Geolocation/Gesture/Accelerometer/etc.

OS Intergration

HCI/HomeScreen/Push Notification/FileSystem/

Background Threads/etc. 

Network 

Latency/Cache/Offline/Network Resilience

Tons of "Hybridzation"

Hybridzation Toke Our Soul, 

Put It Back Into Garden Wall.

Nobody, maybe me

"We believe the web has been the most convincing solution to reaching many devices of differing capabilities."

"If the web doesn’t do something today it’s not because it can’t, or won’t, but rather it is because we haven’t gotten around to implementing that capability yet."

We already walked too far,

down to we had forgotten why embarked.

"PhoneGap is a Polyfill, and the ultimate purpose of PhoneGap is to cease to exist." (2012)

Time To Esc Walled Garden, 

And Back To Open Free Land.

Nobody, maybe me

"Progressive Web Apps:
Escaping Tabs Without Losing Our Soul
(2015)

Introduction to PWA: From What to How 

PWA 101

1. The new application 

     model for Web; 

2. Websites progressively

     become 'apps'.

No.1, The Beginning of First-Class Citizen

Add To HomeScreen

iOS 1.1.3

2008-01-15 

Added section on specifying a web clip icon.

iOS 2.1.0

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"
}

Web App Manifest (SPEC)

<link rel="manifest" href="/manifest.json">

No.2 Network As Progressive Enhancement

Reliable Experience

 

(THIS IS A BROWSER, ACTUALLY)

"We have to make it

very cute cuz you

saw it a lot"

Web is constructed with the assumption that you have put yourself into the "internet mode"

APP CACHE?

(Offline Web App Spec)

<html manifest="cache.appcache">

The "Onion"

In private session ;)

"等了这么久,现在有了 Service Worker 终于可以 do it properly."

SW Showcase

Reliable

Experience

SW Showcase

Caching

On-the-fly

  • Web Workers

  • SharedWorker 

  • Chrome Background Pages

  • Chrome Event Pages

  • !App Cache

Service Worker (SPEC)

HTTPS as Pre-requisite

// 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);
    })
}

Step1 - Register Service Worker 

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());
    })
  )
});

Step2 - On Install & Cache API(SPEC)

You manage what is 'installed' and how it's cached

// WEBIDL
interface ExtendableEvent : Event {
  void waitUntil(Promise<any> f);
};

Tips - ExtendableEvent (SPEC)

Tips - SkipWaiting (SEPC)

// 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);
    })
  );
});

Step3 - On Fetch 

  • You control request routing
  • You control the caches
  • You control the response

Let's It! - the Proxy Servers

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 */})
  )
}

Stale-While-Revalidate & Fallback

Update SW?

// 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);
        })
      );
    })
  );
});

On Activate

Clean-up & Migration.

(SW can be built as progressive enhancement In.)

Architectural

 Revolution

RWD      Media Query        "Mobile First"

PWA      Service Worker    "Offline First"

Ajax       XHR                          "Async First"

Buzzword    Core Technology            Archtechutal Style

Resources & Libraries

No.3 The Killer Features of Mobile OS

Re-engageable

 

“Progressive Web Apps”

The Umbrella Term. 

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

From UED' Pespective

PWA In Production

Visit Google in China

(without bypassing GFW)

     Work Offline                       Caching                   Push Notification

We Got Modern Web Capabilities

"People don't expect a web application to work offline. I know I don't,

I still don't. " 

What we assume user would think

"Hey I saw the URL bar, This is a website!"

"This is an offline

 reliable app!"

What user actually think

"Hey I saw the URL bar, This is a website!"

"This is a bookmark!"

"I aware of it."

What user would think after teaching

"I can install App from Browser(URL)!"

"This is an offline

 reliable app!"

Progressive App

Streamable App

Evergreen App

Im Resistent To Answer This FAQ!

PWA vs. Others

“从纯 Web 到纯 Native,

之间有许多可能的点。”

Web

Hybrid

JS 2 Native

Low capability

High capability

Native

Web

Hybrid

JS 2 Native

Low capability

High capability

Native

 

WE TRIED HYBRID AS WELL...

"In anytime, somebody

trys to reimplement native widgets with HTML, CSS and JavaScript, It always feels like shit."

Compatibility Issue

Regional Issue

Web or Native

"Making the tradeoff for your product"

"Every step on the path to a Progressive Web App makes sense on its own"

It just make Web better.

It's Not Just About Software.

The Belief In Web

"The device wall isn’t something to keep phones in:

it’s for keeping proprietary platforms out"

It's about "Anyone, at any time, can publish anything from anywhere. That is the stuff of revolutions, and our evolution as a species."

We Choose A Hard Route, But We Are Damn Proud.

Nobody, maybe me, reply to the "Web as Adaptive Platform"

"We're alone in

deciding that you should be able to run desktop applications(legacy)

on a phone."

MAKE THE WEB
GREAT AGAIN

Thanks.

Q/A