Pro Yearly is on sale from $80 to $50! »

The Progression of Web Apps @ Fronteers

The Progression of Web Apps @ Fronteers

This talk is about the progression of web apps. And no, that is not a typo. It's about web apps in general, but mostly about Progressive Web Apps. How have we been building web apps so far. And what tools can we use to build native apps using web technologies. And finally what actually are Progressive Web Apps anyway?

De023a9aff4c7a5ede3a81e8c76f17b5?s=128

Niels Leenheer

August 18, 2016
Tweet

Transcript

  1. THE PROGRESSION 
 OF WEB APPS FRONTEERS @ MIRABEAU, 18TH

    AUGUST 2016
  2. None
  3. None
  4. THE PROGRESSION 
 OF WEB APPS

  5. PROGRESSIVE WEB APPS

  6. Photo by Daniel Appelquist

  7. None
  8. PROGRESSIVE

  9. WEB APP

  10. WEB APP

  11. WEB APP

  12. WEB APP

  13. RESPONSIVE

  14. airhorner.com

  15. CONNECTIVITY INDEPENDENT

  16. None
  17. APP-LIKE

  18. APP-LIKE

  19. APP-LIKE MENU Where is my navigation? Click on the hamburger

    menu to get access to all of the navigation options.
  20. FRESH

  21. SAFE

  22. DISCOVERABLE

  23. Hi there! I’m a Web App!

  24. RE-ENGAGEABLE

  25. INSTALLABLE

  26. airhorner.com

  27. airhorner.com

  28. LINKABLE

  29. Airhorner

  30. Airhorner no results found

  31. https://airhorner.com

  32. None
  33. THIS IS NOT A NEW IDEA

  34. None
  35. The full Safari engine is inside of iPhone. 
 And

    so, you can write amazing Web 2.0 and Ajax apps that look exactly and behave exactly like apps on the iPhone. And these apps can integrate perfectly with iPhone services. “ — Steve Jobs, 2007
  36. None
  37. The fundamental problem on the iPhone is not Apple’s App

    Store approval policies, but the iPhone developers’ arrogant disdain for Web technologies. I reviewed the apps I have on my iPhone, and most can be released as a Web app right now. “ — Peter Paul Koch, 2009
  38. ✓ PROGRESSIVE ✓ RESPONSIVE ✓ CONNECTIVITY INDEPENDENT ✓ APP-LIKE ✓

    SAFE ✓ DISCOVERABLE ✓ INSTALLABLE ✓ LINKABLE
  39. LOTS OF UGLY HACKS

  40. LOTS OF BROWSER QUIRKS

  41. NON-STANDARD API’S

  42. NO DEVICE API’S

  43. None
  44. BUILDING NATIVE APPS 
 USING WEB TECHNOLOGY

  45. WHY?

  46. WE KNOW HTML, 
 CSS AND JAVASCRIPT

  47. CROSS PLATFORM
 DEVELOPMENT

  48. GET ACCESS TO NATIVE API’S

  49. THE APP STORE

  50. $ € £ $ ¥ € ¥ £ kr. جد

    ₽ € ¥ ₽
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. PACKAGED WEB APPS

  61. }

  62. HOSTED WEB APPS

  63. } + URL of the hosted web app

  64. None
  65. 2007

  66. <application 
 xmlns="http://ns.adobe.com/air/application/2.5">
 <id>nl.salonhub.Salonhub</id> <filename>Salonhub</filename> <name>Salonhub</name> <versionNumber>6.0.356</versionNumber> <description>De flexibele en

    complete oplossing voor uw kapsalon</description> <initialWindow> <content>platform/air/app/index.html</content> <width>1024</width> <height>768</height> application.xml
  67. adt 
 -package 
 -storetype pkcs12 -keystore cert.p12 -storepass ******

    
 dist/air/Salonhub-6.0.365.air 
 build/air/application.xml 
 -C build/air assets external lib platform settings.js
  68. Salonhub.air

  69. None
  70. 2009

  71. None
  72. PhoneGap is a polyfill, and the ultimate 
 purpose of

    PhoneGap is to cease to exist “ — Brian LeRoux
  73. DEVICE API’S Battery Status Camera Device Motion Device Orientation Geolocation

    Media Capture Splashscreen Vibration Network Information Statusbar Media Files File Transfers Dialogs
  74. PLUGINS

  75. 2012 chrome app

  76. chromebook

  77. chrome web store

  78. None
  79. ×

  80. 2013

  81. None
  82. chromium +

  83. const electron = require('electron'); const app = electron.app; let mainWindow;

    function createWindow () { mainWindow = new electron.BrowserWindow({ width: 800, height: 600 });
 mainWindow.loadURL('file://' + __dirname + '/app/index.html'); mainWindow.on('closed', () => { mainWindow = null }); } app.on('ready', () => { createWindow(); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } launch.js
  84. 2014 Universal Windows Platform

  85. None
  86. None
  87. None
  88. None
  89. None
  90. None
  91. None
  92. npm install -g manifoldjs
 manifoldjs https://airhorner.com -d ~/Projects -p windows10

    manifoldjs package ~/Projects/AirHorner/windows10
  93. UNIVERSAL WINDOWS APPS HAVE ACCESS TO THE
 UNIVERSAL WINDOWS API

  94. DEPLOY ON 
 DESKTOP, MOBILE 
 AND XBOX ONE

  95. AND MANY MORE…

  96. BUT…

  97. DEPENDANT ON THIRD PARTIES

  98. NOT PART OF THE WEB

  99. None
  100. PROGRESSIVE WEB APPS

  101. WEB MANIFEST

  102. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> index.html
  103. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> index.html
  104. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> index.html
  105. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> index.html
  106. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> index.html
  107. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="/icon-32x32.png" sizes="32x32"> <link rel="icon" type="image/png" href="/icon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="/icon-160x160.png" sizes="160x160"> <link rel="icon" type="image/png" href="/icon-196x196.png" sizes="196x196"> index.html
  108. <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon"

    sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="/icon-32x32.png" sizes="32x32"> <link rel="icon" type="image/png" href="/icon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="/icon-160x160.png" sizes="160x160"> <link rel="icon" type="image/png" href="/icon-196x196.png" sizes="196x196"> index.html
  109. <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon"

    sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="/icon-32x32.png" sizes="32x32"> <link rel="icon" type="image/png" href="/icon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="/icon-160x160.png" sizes="160x160"> <link rel="icon" type="image/png" href="/icon-196x196.png" sizes="196x196"> <meta name="application-name" content="HTML5test"> <meta name="msapplication-TileColor" content="#0092bf"> <meta name="msapplication-TileImage" content="/mstile-144x144.png"> index.html
  110. PLACE EVERYTHING 
 IN A SEPARATE JSON FILE

  111. { "name": "HTML5test", "theme_color": "#0092bf", "display": "standalone",
 "icons": [ {

    "src": "/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icon-256x256.png", "sizes": "256x256", "type": "image/png" }, { "src": "/icon-512x512.png", "sizes": "512x512", "type": "image/png" } manifest.json
  112. APP NAME ICONS
 THEME COLORS SETTINGS

  113. LAUNCH FULL SCREEN { "display": "standalone"
 }

  114. LIMIT SCREEN ORIENTATION { "orientation": "portrait"
 }

  115. START A DIFFERENT URL { "start_url": "standalone.html"
 }

  116. None
  117. <!doctype> <html> <head> <title>HTML5test - How well does your browser

    support HTML5?</title> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png"> <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"> <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> index.html
  118. <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon"

    sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="/icon-32x32.png" sizes="32x32"> <link rel="icon" type="image/png" href="/icon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="/icon-160x160.png" sizes="160x160"> <link rel="icon" type="image/png" href="/icon-196x196.png" sizes="196x196"> <meta name="application-name" content="HTML5test"> <meta name="msapplication-TileColor" content="#0092bf"> <meta name="msapplication-TileImage" content="/mstile-144x144.png"> index.html
  119. <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png"> <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"> <link rel="apple-touch-icon"

    sizes="60x60" href="/apple-icon-60x60.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"> <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"> <meta name="mobile-web-app-capable" content="yes"> <meta name="theme-color" content="#0092bf"> <link rel="icon" type="image/png" href="/icon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="/icon-32x32.png" sizes="32x32"> <link rel="icon" type="image/png" href="/icon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="/icon-160x160.png" sizes="160x160"> <link rel="icon" type="image/png" href="/icon-196x196.png" sizes="196x196"> <meta name="application-name" content="HTML5test"> <meta name="msapplication-TileColor" content="#0092bf"> <meta name="msapplication-TileImage" content="/mstile-144x144.png"> <link rel="manifest" href="/manifest.json"> index.html
  120. NOT POSSIBLE TO SPECIFY 
 DIFFERENT ICON STYLES FOR 


    DIFFERENT PLATFORMS :-(
  121. None
  122. BROWSER SUPPORT Chrome 39 Opera 32

  123. DEVICE API’S

  124. navigator.vibrate(200);
 
 navigator.vibrate([100, 200, 200, 200, 500]); VIBRATION

  125. navigator.getUserMedia( { audio: true, video: { width: 1280, height: 720

    } }, function(stream) { }, function(err) { } }); CAMERA & MICROPHONE
  126. BATTERY navigator.getBattery().then(function(battery) {
 battery.addEventListener('chargingchange', function() { console.log(battery.charging); }); battery.addEventListener('levelchange', function()

    { console.log(battery.level); }); 
 });
  127. GEOLOCATION
 DEVICE MOTION
 DEVICE ORIENTATION AMBIENT LIGHT BLUETOOTH

  128. SERVICE WORKERS

  129. Application Cache is a Douchebag! “ — Jake Archibald

  130. None
  131. None
  132. None
  133. × ?

  134. if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js'); }

  135. None
  136. None
  137. ×

  138. THE SERVICE WORKER RUNS JAVASCRIPT CODE :-)

  139. self.addEventListener('install', function(event) { // Perform install steps }); sw.js

  140. self.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) { return cache.addAll([ '/index.html', '/styles/main.css',

    '/scripts/main.js' ]); }) ); }); sw.js
  141. return cache.addAll([ '/index.html', '/styles/main.css', '/scripts/main.js' ]); }) ); }); self.addEventListener('fetch',

    function(event) { // Intercept network requests }); sw.js
  142. return cache.addAll([ '/index.html', '/styles/main.css', '/scripts/main.js' ]); }) ); }); self.addEventListener('fetch',

    function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; } return fetch(event.request); } ) ); }); sw.js
  143. THE SERVICE WORKER IS 
 INDEPENDENT OF YOUR WEBPAGE

  144. BROWSER SUPPORT Chrome 40 Opera 27 Firefox 44 Samsung 4

    Edge (behind flag)
  145. PUSH NOTIFICATIONS

  146. WEB PUSH 
 API WEB PUSH 
 PROTOCOL SERVICE WORKERS

    WEB NOTIFICATIONS
  147. None
  148. navigator.serviceWorker.ready.then(function(sw) { sw.pushManager.subscribe().then(function(subscription) { // Send subscription to server })

    })
  149. Send the subscription data to our server, 
 including the

    URL of the push server
  150. The webpage is closed and 
 the service worker is

    sleeping
  151. The server has new 
 information for the user

  152. The server sends a message to the 
 push server

    using the Web Push protocol
  153. The push server wakes up 
 the service worker

  154. self.addEventListener('push', function(event) { // We received a push message });

  155. (optional)

  156. self.registration.showNotification('Attention!', { body: 'Push message received', icon: 'icon.png' }); (optional)

  157. The webpage is still closed and 
 the service worker

    is sleeping again
  158. BROWSER SUPPORT Chrome 42 Opera 30 Firefox 44 Samsung 4

    Edge (behind flag)
  159. WEB PAYMENTS

  160. Start payment process by clicking a button in your app

  161. Start payment process by clicking a button in your app

    var methodData = [ { supportedMethods: ["visa", "mastercard"] } ];
  162. Start payment process by clicking a button in your app

    var details = { displayItems: [ { label: "Donation", amount: { currency: "USD", value : "55.00" } } ], total: { label: "Total", amount: { currency: "USD", value : "55.00" } } };
  163. var request = new PaymentRequest( methodData, // required payment method

    data details // required transaction information );
  164. request.show().then(function(response) { // success }).catch(function(err) { // failed });

  165. Select your payment 
 method or use the default

  166. Enter your CVC code or confirm with your fingerprint

  167. Done!


  168. BROWSER SUPPORT Chrome Edge (behind flag)

  169. BUT WHAT ABOUT 
 THE DESKTOP?

  170. BROWSER DEVELOPMENT 
 IS DRIVEN BY MOBILE

  171. None
  172. BUT…

  173. NATIVE PWA SUPPORT 
 IN THE WINDOWS STORE

  174. None
  175. BUT WHAT ABOUT 
 APPLE?

  176. THIS IS NOT A GOOGLE THING

  177. None
  178. BUT…

  179. ?

  180. ? ×

  181. THE OLD HACKS STILL WORK

  182. MAYBE, HOPEFULLY, POSSIBLY
 THIS WILL CHANGE IN THE FUTURE

  183. OR NOT

  184. None
  185. None
  186. None
  187. THANK YOU! @HTML5TEST