Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Progressive Web Apps are here!

Progressive Web Apps use modern web capabilities to deliver an app-like user experience. They evolve from pages in browser tabs to immersive, top-level apps, maintaining the web's low friction at every moment.

They are reliable, fast, engaging and delivering amazing UX to end users. And they are here!

The slides are from my talk at http://2018.symfonycamp.org.ua/

  • Identifiez-vous pour voir les commentaires

Progressive Web Apps are here!

  1. 1. Progressive Web Apps are here! Antonio Perić-Mažar, Locastic 27.10.2018., #sfcampua
  2. 2. Antonio Perić-Mažar CEO @ Locastic Co-Founder @ Blockada antonio@locastic.com @antonioperic
  3. 3. Locastic • We help clients create amazing web and mobile apps (since 2011) • mobile development • web development • UX/UI • Training and Consulting • Shift Conference, Symfony Croatia • www.locastic.com t: @locastic
  4. 4. Not a Symfony talk!
  5. 5. [Mobile] User Experience on Web
  6. 6. And trust me… you will never had enough cheese
  7. 7. “I don't care how many kick-ass Visio architecture diagrams you have; as far as the user is concerned, the UI is the application. I know UI US HARD, but you have to build an impressive UI if you want to be taken seriously. Give your UI the high priority it deserves.” Jeff Atwood, Coding Horror blog
  8. 8. Capebility Reach
  9. 9. “A Progressive Web App uses modern web capabilities to deliver an app-like user experience.”
  10. 10. “A Progressive Web App uses modern web capabilities to deliver an app-like user experience.”
  11. 11. PWA is: • Progressive - Works for every user, regardless of browser choice because it's built with progressive enhancement as a core tenet. • Responsive - Fits any form factor: desktop, mobile, tablet, or whatever is next. • Connectivity independent - Enhanced with service workers to work offline or on low-quality networks. • App-like - Feels like an app, because the app shell model separates the application functionality from application content . • Fresh - Always up-to-date thanks to the service worker update process.
  12. 12. PWA is: • Safe - Served via HTTPS to prevent snooping and to ensure content hasn't been tampered with. • Discoverable - Is identifiable as an "application" thanks to W3C manifest and service worker registration scope, allowing search engines to find it. • Re-engageable - Makes re-engagement easy through features like push notifications. • Installable - Allows users to add apps they find most useful to their home screen without the hassle of an app store. • Linkable - Easily share the application via URL, does not require complex installation.
  13. 13. Fast Integrated Reliable Engaging 4 things to focus on
  14. 14. Fast Integrated Reliable Engaging
  15. 15. Fast • No junky scrolling • No slow load performance • Measure and improve all the time • Bad connection (or no connection) is not excuse
  16. 16. 53% of users abandon sites that take longer than 3 seconds to load
  17. 17. https://cloudfour.com/thinks/ios-doesnt-support-progressive-web-apps-so-what/
  18. 18. App shell model • Reliable performance that is consistently fast • Native-like interactions • Economical use of data
  19. 19. Fast Integrated Reliable Engaging
  20. 20. Integrated • User should not reach browser to reach your app • They should be able to interact same as with any other app on their device • They expect to have all possibilities as other apps • Users should be able to start app from their home screen
  21. 21. https://www.mobigyaan.com/android-8-0-oreo-vs-ios-11-which-is-better
  22. 22. https://techcrunch.com/2017/08/25/majority-of-u-s-consumers-still-download-zero-apps-per-month-says-comscore/
  23. 23. https://techcrunch.com/2017/08/25/majority-of-u-s-consumers-still-download-zero-apps-per-month-says-comscore/
  24. 24. https://www.technology.org/2017/07/28/progressive-web-apps-vs-native-which-is-better-for-your-business/
  25. 25. 80% users intentionally moved apps to their home screen
  26. 26. Broken experience • Required user interaction • Where it will start? • Would it work offline? https://medium.com/@saigeleslie/how-to-create-a-progressive-web-app-with-react-in-5-mins-or-less-3aae3fe98902
  27. 27. Web manifest • Simple JSON file • Tell browsers about your app and how it should behave once app is ‘installed’ • Having manifest is required to show add to home screen pop-up • Works for desktop and mobile apps (chrome) • https://manifest-validator.appspot.com/ • https://app-manifest.firebaseapp.com/
  28. 28. {    "background_color":"#ffffff",    "description":"It's what's happening. From breaking news and entertainment, sports  and politics, to big events and everyday interests.",    "display":"standalone",    "gcm_sender_id":"49625052041",    "gcm_user_visible_only":true,    "icons":[       {          "src":"https://abs.twimg.com/responsive-web/web/ltr/icon-default. 604e2486a34a2f6e.png",          "sizes":"192x192",          "type":"image/png"       },       {          "src":"https://abs.twimg.com/responsive-web/web/ltr/icon-default. 604e2486a34a2f6e.png",          "sizes":"512x512",          "type":"image/png"       }    ],    "name":"Twitter",    "share_target":{       "action":"compose/tweet",       "params":{          "title":"title",          "text":"text",          "url":"url"       }    },    "short_name":"Twitter",    "start_url":"/",    "theme_color":"#ffffff",    “scope":"/" }
  29. 29. {    "background_color":"#ffffff",    "display":"standalone",    "icons":[  …    ],    "name":"Twitter",    "short_name":"Twitter",    "start_url":"/",    "theme_color":"#ffffff",    “scope":"/" } <link rel="manifest" href="/manifest.json"> You can add it now to 
 your app
  30. 30. What are the criteria? • The web app is not already installed • Meets a user engagement heuristic (currently, the user has interacted with the domain for at least 30 seconds) • Served over HTTPS (required for service workers) • Has registered a service worker with a fetch event handler
  31. 31. What are the criteria? • Includes a web app manifest that includes: • Short name or name • Icons must include a 192px and a 512px sized icons • start_url • Display must be: fullscreen, standalone, or minimal- ui
  32. 32. What are the criteria? • When these criteria are met, Chrome will fire a beforeinstallprompt event that you can use to prompt the user to install your Progressive Web App. let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { // Prevent Chrome 67 and earlier from automatically showing the prompt e.preventDefault(); // Stash the event so it can be triggered later. deferredPrompt = e; });
  33. 33. What are the criteria? btnAdd.addEventListener('click', (e) => { // hide our user interface that shows our A2HS button btnAdd.style.display = 'none'; // Show the prompt deferredPrompt.prompt(); // Wait for the user to respond to the prompt deferredPrompt.userChoice .then((choiceResult) => { if (choiceResult.outcome === 'accepted') { console.log('User accepted the A2HS prompt'); } else { console.log('User dismissed the A2HS prompt'); } deferredPrompt = null; }); });
  34. 34. https://ponyfoo.com/articles/progressive-app-serviceworker
  35. 35. 40% higher interaction rate from Home screen
  36. 36. Web Payment API!
  37. 37. 66% of purchases on mobile are on the web
  38. 38. 1/3 of purchases on Web are via mobile That means the UX 
 is BROKEN!
  39. 39. Checkout forms today: • Manual • Tedious • Slow • N-taps http://www.alyssatucker.com/improving-hollars-ios-checkout-process/
  40. 40. Autofill - step forward • Autocomplete attributes • 30% faster • Automatic • Simple • Slow • n-taps http://www.alyssatucker.com/improving-hollars-ios-checkout-process/
  41. 41. Web Payment API!
  42. 42. // Supported payment methods const paymentMethods = [{ supportedMethods: 'basic-card', data: { supportedNetworks: [ 'visa', 'mastercard', 'amex', 'discover', 'diners', 'jcb', 'unionpay' ] } }, { supportedMethods: 'https://bobpay.xyz/pay', }]; Define payment methods
  43. 43. var options = { requestShipping: true, requestPayerEmail: true, requestPayerPhone: true, requestPayerName: true, shippingType: 'delivery' }; var request = new PaymentRequest(paymentMethods, paymentDetails, paymentOptions); Setup your payment options
  44. 44. request.show().then(response => { // [process payment] // send to a PSP etc. response.complete('success'); }); Show payment screen
  45. 45. { // example response "methodName": "basic-card", "details": { "cardholderName": "Larry Page", "cardNumber": "4111111111111111", "expiryMonth": "12", "expiryYear": "2020", "cardSecurityCode": "111", "billingAddress": { ... } }, "payerName": "Larry Page", "payerPhone": "212-555-1212", "payerEmail": "user@example.com" } Payment response
  46. 46. Web Payment API! • Automatic • Simple • Fast • 1-tap • Supportes payment gatway,
 or some applications payment 
 (Google Pay) https://paymentrequest.show/images/pr-woocommerce.gif
  47. 47. More APIs • Media Session • Media Capture API • Casting support • Web bluetooth • Web Share
  48. 48. More APIs • Media Session • Media Capture API • Casting support • Web bluetooth • Web Share
  49. 49. Remember users expect to be able to interact with your app in the same way that they do all of the other apps on their device
  50. 50. Fast Integrated Reliable Engaging
  51. 51. Reliable Reliability means, never showing the Downsaur
  52. 52. Reliable • The quality of a network connection can be affected by a number of factors such as: • Poor coverage of a provider. • Extreme weather conditions. • Power outages. • Users travelling into “dead zones” such as buildings that block their network connections. • Travelling on a train and going through a tunnel. • Internet connection is managed by a third party and time boxed when it will be active or inactive like in an airport or hotel. • Cultural practises that require limited or no internet access at specific times or days.
  53. 53. Reliable • We need instant loading offline • 60% of mobile connection is 2G • Fast Application is UX • 14 sec to load average website on 4g • 19 sec to load average website on 3G
  54. 54. Service Workers
  55. 55. Service Workers
  56. 56. Service WorkersService Workers
  57. 57. Service Workers • Rich offline experiences • Background syncs • Push notifications • …
  58. 58. Service Workers • Script that browser runs in background, separated from web page • It is Javascript worker, so it cannot access to DOM directly • Service worker is a programmable network proxy, allowing you to control how network requests from your page are handled.
  59. 59. Service Workers • It's terminated when not in use, and restarted when it's next needed, so you cannot rely on global state within a service worker's onfetch and onmessage handlers. • Service workers make extensive use of promises • Service worker is for second load
  60. 60. Service Workers lifecycle
  61. 61. Register a Service Worker if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); }
  62. 62. On Install var CACHE_NAME = 'my-site-cache-v1'; var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); }) ); });
  63. 63. Cache and return requests self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } return fetch(event.request); } ) ); });
  64. 64. Service workers Events • On install - as a dependency • On install - not as a dependency • On activate • On user interaction • On network response • Stale-while-revalidate • On push message • On background-sync
  65. 65. Update Service Worker • Update your service worker JavaScript file. When the user navigates to your site, the browser tries to redownload the script file that defined the service worker in the background. If there is even a byte's difference in the service worker file compared to what it currently has, it considers it new. • Your new service worker will be started and the install event will be fired. • At this point the old service worker is still controlling the current pages so the new service worker will enter a waiting state. • When the currently open pages of your site are closed, the old service worker will be killed and the new service worker will take control. • Once your new service worker takes control, its activate event will be fired.
  66. 66. Update Service Worker • self.skipWaiting() • Skips waiting for refresh to start using new SW
  67. 67. On User Interaction
  68. 68. // on user interaction document.querySelector('.cache-article').addEventListener('click', function(event) { event.preventDefault(); var id = this.dataset.articleId; caches.open('mysite-article-' + id).then(function(cache) { fetch('/get-article-urls?id=' + id).then(function(response) { // /get-article-urls returns a JSON-encoded array of // resource URLs that a given article depends on return response.json(); }).then(function(urls) { cache.addAll(urls); }); }); });
  69. 69. On Network response
  70. 70. self.addEventListener('fetch', function(event) { event.respondWith( caches.open('mysite-dynamic').then(function(cache) { return cache.match(event.request).then(function (response) { return response || fetch(event.request).then(function(response) { cache.put(event.request, response.clone()); return response; }); }); }) ); });
  71. 71. On Background Sync
  72. 72. self.addEventListener('sync', function(event) { if (event.id == 'update-leaderboard') { event.waitUntil( caches.open('mygame-dynamic').then(function(cache) { return cache.add('/leaderboard.json'); }) ); } });
  73. 73. SW: Serving suggestions - responding to requests • Cache only • Network only • Cache, falling back to network • Cache & network race • Network falling back to cache • Cache then network • Generic fallback • ServiceWorker-side templating
  74. 74. Cache only
  75. 75. Cache only self.addEventListener('fetch', function(event) { // If a match isn't found in the cache, the response // will look like a connection error event.respondWith(caches.match(event.request)); });
  76. 76. Network only
  77. 77. Network only self.addEventListener('fetch', function(event) { event.respondWith(fetch(event.request)); // or simply don't call event.respondWith, which // will result in default browser behaviour });
  78. 78. Cache, falling back to network
  79. 79. Cache, falling back to network self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); });
  80. 80. Network, falling back to Cache
  81. 81. Network, falling back to Cache self.addEventListener('fetch', function(event) { event.respondWith( fetch(event.request).catch(function() { return caches.match(event.request); }) ); });
  82. 82. Cache, than Network
  83. 83. Cache, than Networkvar networkDataReceived = false; startSpinner(); // fetch fresh data var networkUpdate = fetch('/data.json').then(function(response) { return response.json(); }).then(function(data) { networkDataReceived = true; updatePage(data); }); // fetch cached data caches.match('/data.json').then(function(response) { if (!response) throw Error("No data"); return response.json(); }).then(function(data) { // don't overwrite newer network data if (!networkDataReceived) { updatePage(data); } }).catch(function() { // we didn't get cached data, the network is our last hope: return networkUpdate; }).catch(showErrorMessage).then(stopSpinner);
  84. 84. Cache, than Network self.addEventListener('fetch', function(event) { event.respondWith( caches.open('mysite-dynamic').then(function(cache) { return fetch(event.request).then(function(response) { cache.put(event.request, response.clone()); return response; }); }) ); });
  85. 85. Reliable conclusion • Think how you design for the success, failure and instability of a network connection • Data may be expensive, so be considerate to the user • Make sure performance is part of your design process and UX • Try to provide offline by default if your app doesn't require much data • Inform users of their current state and of changes in states • https://serviceworke.rs/ - different examples
  86. 86. Your goal is to provide a good experience that lessens the impact of changes in connectivity
  87. 87. Fast Integrated Reliable Engaging
  88. 88. Engaging • Charming and Attractive • Shift way how we think in patterns and designs from web patterns to some native patterns • Push notifications (browser doesn’t need to be opened) • Push Notification API
  89. 89. Engaging
  90. 90. What makes good notification Push. Push. Back upon now. (Courtesy Enrique Iglesias)
  91. 91. What makes good notification • Timely - I feel I need and it matters now • Precise - specific info, what happens • Personal - make it personal
  92. 92. What makes good notification
  93. 93. https://www.slideshare.net/SeulgiChoi4/pwa-push-notification
  94. 94. https://www.slideshare.net/SeulgiChoi4/pwa-push-notification
  95. 95. self.addEventListener('push', function(event) { if (event.data.text() == 'new-email') { event.waitUntil( caches.open('mysite-dynamic').then(function(cache) { return fetch('/inbox.json').then(function(response) { cache.put('/inbox.json', response.clone()); return response.json(); }); }).then(function(emails) { registration.showNotification("New email", { body: "From " + emails[0].from.name tag: "new-email" }); }) ); } }); self.addEventListener('notificationclick', function(event) { if (event.notification.tag == 'new-email') { // Assume that all of the resources needed to render // /inbox/ have previously been cached, e.g. as part // of the install handler. new WindowClient('/inbox/'); } });
  96. 96. Push Notifications { "body": "Did you make a $1,000,000 purchase at Dr. Evil...", "icon": "images/ccard.png", "vibrate": [200, 100, 200, 100, 200, 100, 400], "tag": "request", "actions": [ { "action": "yes", "title": "Yes", "icon": "images/yes.png" }, { "action": "no", "title": "No", "icon": "images/no.png" } ] }
  97. 97. 43% agrees to an app’s request to allow push notifications
  98. 98. Credentials API! • Removes friction from sign-in flows - Users can be automatically signed back into a site even if their session has expired or they saved credentials on another device. • Allows one tap sign in with account chooser - Users can choose an account in a native account chooser. • Stores credentials - Your application can store either a username and password combination or even federated account details. These credentials can be synced across devices by the browser.
  99. 99. Tools!
  100. 100. Lighthouse
  101. 101. Some show case!
  102. 102. 65% increase in page per session 75% increase in Tweets sent
 20% decrease in bounce rate Twitter Lite
  103. 103. 76% higher conversation across browsers 4x higher interaction rate from Add to screen Increased usage of native apps also Alibaba
  104. 104. 80%+ conversation 54% smaller than Android app 120% smaller than iOS app BookMyShow
  105. 105. Cut load times from 11.91 to 4.69 seconds 90% smaller than Native Android App https://medium.com/@addyosmani/a-tinder-progressive-web-app-performance- case-study-78919d98ece0 Tinder
  106. 106. Myths about PWA!
  107. 107. PWAs are only for offline apps
  108. 108. PWAs are a mobile thing
  109. 109. PWAs are a Google-only thing
  110. 110. PWAs are not ready yet
  111. 111. https://pwa.rocks/
  112. 112. Don’t be driven with hype, choose the best fit for your project
  113. 113. It is not about PWA vs Native apps, it is about Users
  114. 114. Thank you!
  115. 115. QnA?

×