Presentation is loading. Please wait.

Presentation is loading. Please wait.

Escaping tabs with progressive web apps

Similar presentations


Presentation on theme: "Escaping tabs with progressive web apps"— Presentation transcript:

1 Escaping tabs with progressive web apps
+Ilya Grigorik @igrigorik It’s been long, but also exciting and informative morning.. You can’t help it though, after a few hours your attention just starts to wander. Thankfully, my colleague Paul Kinlan recently built an indispensible app for just such an occasion…. (demo) ... Yes, it’s an airhorn. Everyone needs one, and now you have one… Well, almost, how do you get it?

2 Load store Find in store Click install Accept permissions
Download, wait... Use I’ve hopefully convinced you that you want it - discovery, check. Go to the app store, search for it, install it. Click install, and accept permissions. Eh, why does this app need permission for push notifications? Oh well, whatever, accept… or not. Wait to download Go to homescreen, launch it Enjoy Nothing new here, right? There is a problem though. Every step is an opportunity to lose the user…

3 Load store 800 Let’s say I intrigued ~1000 of you Find in store 640 “In a consumer mobile app, every step you make a user perform before they get value out of your app will cost you ~20% of users...” Click install 512 Accept permissions 410 Download, wait... 328 Use 262 The loss rate can be as high as 20% per step. So, if I convince a ~1000 of you to start this process, less than 1/3rd will make it to the end. Each step adds friction, and each step delays the gratification of using that glorious airhorn. What if there was a better way?

4 Just go to No install process, instant gratification, and everyone gets to enjoy the benefits of this awesome app. Except, of course.. That’s not the full story, right? Web excels at ephemeral interactions, but it doesn’t have the same engagement model as native apps: homescreen integration, offline, push notification, and all the rest. Well, what if I told you that we can, in fact, do all of those things on the web. Better, we can eliminate a lot of the friction we just saw. There is no reason why we can’t have instant gratification and the app-like features that both developers and users want and need. We can build progressive apps.

5 Load store Load URL Find in store Use Click install Accept permissions
Background install Download, wait... Add to Homescreen Use ... What’s a progressive app? It’s a link you navigate to, or search for using your favorite search engine, just like any other page. Except, in the background the page can progressively upgrade its capabilities. How? Let’s talk about Service Worker.

6 Load URL Service Worker begins the progressive upgrade by initiating the registration process while the user is interacting with the page... Use Progressive upgrade... // register Service Worker in index.html if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/v1/static/sw.js').then(reg => { console.log("Registration succeeded!"); }).catch(error => { console.log("Registration failed with" + error); }); } The same page that you’ve opened and interacting with contains a script that registers a Service Worker. The ServiceWorker is a background worker that runs on a separate thread and upgrades your tab with additional capabilities.

7 You manage what is “installed” and how it is cached.
Activated Install self.addEventListener('install', function(e) { e.waitUntil(caches.open('airhorner').then(function(cache) { return cache.addAll([ '/index.html', '/styles/main.css', '/scripts/main.min.js', '/sounds/airhorn.mp3' ]); }) ); }); You manage what is “installed” and how it is cached. For example, if the registration is successful the Service Worker fires an install event, at which point you can execute arbitrary logic to “install” your application. You can prefetch resources and cache them in a local cache. In effect, we’re running a fully scriptable install; no bulky zipfiles and we have file-level control over what is fetched, how its cached and how it is updated.

8 Use Register SW Activated Error Idle Terminated Active With Service Worker registration in place the application upgrades itself with new capabilities that kick-in on next load (or, immediately). Once the install process is finished, the service worker is activated and we unlock a new life cycle and many new capabilities for our app. Let’s take a look at a few examples...

9 Once activated, Service Worker intercepts all requests, including those for cross-origin resources!
this.addEventListener('fetch', function(e) { console.log(e.request); console.log(e.request.url); console.log(e.request.method); console.log(e.request.headers); }); // You can generate any response you like... this.addEventListener('fetch', function(e) { e.respondWith( new Response( // Constructor "<h1>OH HAI!</h1>", // String or ByteArray { statusCode: 200, headers: { /* ... */ } } )); }); Whenever a new request is initiated our Service Worker is woken up and receives a fetch event that it can respond to. We have full control over how we respond: we can inspect the request, we can rewrite it, and we can even synthesize responses right from within the ServiceWorker. All of this is completely transparent to the application. In effect, ServiceWorker acts as a scriptable proxy.

10 You can also query your cache(s), and much more…
this.addEventListener('fetch', function(e) { e.respondWith( // check the cache first caches.match(e.request).then(function(response) { return response || // if it's in the cache, return it fetch(e.request); // else, go to the network }) ); }); You control request routing You control the cache(s) You control the response Of course, we can also interrogate any of the caches we may have populated earlier and use those responses to fulfill the request. With Service worker in place your application can respond to requests regardless of users connectivity. You can respond with cached data when the user is offline and you can store data to be delivered later once the user is back online. You’re in full control over the request flow.

11 Let’s add ourselves to the home screen…
<link rel="manifest" href="manifest.json"> { "name": "Airhorner", "start_url": "/", "display": "standalone", "orientation": "portrait", "background_color": "#2196F3", "icons": [{ "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png","density": "4.0" }] } Our app looks, feels, and smells like any other app on your phone. Next up, let’s add ourselves to the homescreen. To do so, we simply add a manifest file that provides some informaiton about the app - its name, icon, and a few additional bits. With that in place, the browser detects that this app has an active service and manifest and prompts the user with a request to add the app to the homescreen. With that in place, and as you can see from the demo, our app is launchable from the home screen, is fully controlled by the service worker and offline friendly.. and indistiguishable from any other app on your device. Well, except for the fact that we didn’t have to touch any appstore and building all this using standard web technologies.

12 Let’s upgrade our capabilities and ask for permissions...
Notification.requestPermission(function(result) { if (result === 'denied') { console.log('Permission denied'); } else if (result === 'default') { console.log('Permission request was dismissed.'); } else { console.log('Permission granted! Notification ahoy!'); } }); No need to declare your permissions upfront. Ask for permissions when you need them and as you need them. Next up, let’s upgrade our app and ask for notification permissions. Wouldn’t it be nice if we could nudge our coworkers via Airhorn notifications? It’s the next killer app. The implementation is simple, we ask for notification permissions and wait for the users decision. There is no need to declare these permissions upfront, in fact you don’t want to.. Users don’t like up-front prompts and permission requests without understanding the context for why they’re needed. Instead, we’re going to ask for permissions when the user requests to enable notifications… Experience shows that this leads to much lower user friction and higher opt-in rates.

13 Use Register SW Activated Error Idle Terminated Active Service Worker enables the app to live outside of the user interaction life-cycle. The worker can be started by the browser and run in the background. Ok, so we have our permissions, now what? How do we push a remote notification? Service Worker to the rescue, again. Recall that the service worker has an independent lifecycle from the actual tab. It can run in the background independently of the tab and the browser can start and stop it as needed.

14 Your server GCM server Wake up Service Worker
self.addEventListener('push', function(e) { var data = e.data.json(); var title = data.title; var message = data.message; return new Notification(title, { body: message, icon: 'images/touch/chrome-touch-icon-192x192.png' }); }); To deliver a push notification we push a notification to the Google Cloud Messaging server, which in turn pushes the notification to the device. The notification is delivered to Chrome, which waks up the relevant worker and dispatches a push event. From there, your code is back in control and determines how to react to the notification. It can inspect the data attached to the notification and display it to the user, or deal with it in the background.

15 User clicks on notification
self.addEventListener('notificationclick', function(event) { var data = event.notification.data; clients.openWindow(data.url); }); You control what the notifications display, how they are grouped, what actions the user has, and how the application responds to user interaction. Assuming we decide to display the notification, we also get a callback with the users reply.. at which point we can determine the relevant action, like opening our app, navigating the user to a particular URL, or doing some other app-specific task.

16 Tab independent life-cycle that enables new capabilities. fetch
Progressive web apps begin their life as a tab. Linkable, discoverable, safe, responsive. Load URL Use Background install They are installable. Tab independent life-cycle that enables new capabilities. fetch push They minimize friction. Permissions are requested on as and when needed basis. notificationclick message They are the future of web apps Offline, push notifications, sync, and much more… sync And, there is more.. Using a similar workflow we can also perform background sync, we can exchange messages between the active tab and the worker, request access to additional capabilities like camera and microphone access, query network information, and much more. You have access to all the APIs exposed by the web platform, including.. of course, the performance APIs that will help you measure all the aspects of your application. In summary, progressive apps being their life as a regular tab. ... ...

17 The worker is what enables our progressive app to live independently of the visible app. What else can we do? We can request a background sync. If we’re offline the sync handler will be automatically called next time the user is online. Future: geofence, beacons, and other background triggers. Refs


Download ppt "Escaping tabs with progressive web apps"

Similar presentations


Ads by Google