The Progression of Web Apps @ GDG DevFest Belgium

The Progression of Web Apps @ GDG DevFest Belgium

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

October 23, 2016
Tweet

Transcript

  1. THE PROGRESSION 
 OF WEB APPS GDG DEVFEST BELGIUM, 23RD

    OCTOBER 2016
  2. THE PROGRESSION 
 OF WEB APPS GDG DEVFEST BELGIUM, 23RD

    OCTOBER 2016
  3. None
  4. None
  5. THE PROGRESSION 
 OF WEB APPS

  6. THE PROGRESSION 
 OF WEB APPS

  7. PROGRESSIVE WEB APPS

  8. Photo by Daniel Appelquist

  9. None
  10. PROGRESSIVE

  11. RESPONSIVE

  12. CONNECTIVITY INDEPENDENT

  13. APP-LIKE

  14. FRESH

  15. SAFE

  16. DISCOVERABLE

  17. RE-ENGAGEABLE

  18. INSTALLABLE

  19. LINKABLE

  20. None
  21. PROGRESSIVE

  22. WEB APP

  23. RESPONSIVE

  24. airhorner.com

  25. CONNECTIVITY INDEPENDENT

  26. None
  27. APP-LIKE MENU Where is my navigation? Click on the hamburger

    menu to get access to all of the navigation options.
  28. APP-LIKE

  29. FRESH

  30. None
  31. FRESH

  32. SAFE

  33. DISCOVERABLE

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

  35. RE-ENGAGEABLE Something not very
 important has happened Battery is almost

    empty,
 connect your charger Someone you hardly know
 posted what he just ate This is a test pushmessage 
 on acceptation. You have 4 app updates
 available
  36. None
  37. INSTALLABLE

  38. airhorner.com The Airhorner
 airhorner.com ADD TO HOMESCREEN ×

  39. LINKABLE

  40. Airhorner

  41. Airhorner no results found

  42. https://airhorner.com

  43. None
  44. None
  45. THIS IS NOT A NEW IDEA

  46. None
  47. 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
  48. None
  49. None
  50. None
  51. None
  52. 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
  53. 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
  54. None
  55. ✓ PROGRESSIVE ✓ RESPONSIVE ✓ CONNECTIVITY INDEPENDENT ✓ APP-LIKE ✓

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

  57. LOTS OF BROWSER QUIRKS

  58. NON-STANDARD API’S

  59. NO DEVICE API’S

  60. None
  61. BUILDING NATIVE APPS 
 USING WEB TECHNOLOGY

  62. WHY?

  63. WE KNOW HTML, 
 CSS AND JAVASCRIPT

  64. CROSS PLATFORM
 DEVELOPMENT

  65. GET ACCESS TO NATIVE API’S

  66. THE APP STORE

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

    ₽ € ¥ ₽
  68. None
  69. None
  70. None
  71. None
  72. None
  73. None
  74. None
  75. None
  76. None
  77. None
  78. None
  79. None
  80. PACKAGED WEB APPS

  81. }

  82. HOSTED WEB APPS

  83. } + URL of the hosted web app

  84. None
  85. 2007

  86. <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
  87. 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
  88. Salonhub.air

  89. None
  90. 2007

  91. 2007

  92. 2009

  93. DEVICE API’S Battery Status Camera Device Motion Device Orientation Geolocation

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

  95. PhoneGap is a polyfill, and the ultimate 
 purpose of

    PhoneGap is to cease to exist “ — Brian LeRoux
  96. 2009

  97. 2012 chrome app

  98. chromebook

  99. chrome web store

  100. 2012 chrome app

  101. 2013

  102. None
  103. chromium +

  104. 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
  105. 2013

  106. 2013

  107. 2014 Universal Windows Platform

  108. None
  109. None
  110. None
  111. None
  112. None
  113. None
  114. None
  115. npm install -g manifoldjs
 manifoldjs https://airhorner.com -d ~/Projects -p windows10

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

  117. DEPLOY ON 
 DESKTOP, MOBILE 
 AND XBOX ONE

  118. 2014 Universal Windows Platform

  119. AND MANY MORE…

  120. BUT…

  121. DEPENDANT ON THIRD PARTIES

  122. NOT PART OF THE WEB

  123. None
  124. PROGRESSIVE WEB APPS

  125. WEB MANIFEST

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

    support HTML5?</title> index.html
  127. <!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
  128. <!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
  129. <!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
  130. <!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
  131. <!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
  132. <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
  133. <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
  134. PLACE EVERYTHING 
 IN A SEPARATE JSON FILE

  135. { "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
  136. APP NAME ICONS
 THEME COLORS SETTINGS

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

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

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

  140. None
  141. <!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
  142. <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
  143. <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
  144. BROWSER SUPPORT Chrome 39 Opera 32

  145. DEVICE API’S

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

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

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

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

  150. SERVICE WORKERS

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

  152. None
  153. None
  154. None
  155. × ?

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

  157. None
  158. None
  159. ×

  160. THE SERVICE WORKER RUNS JAVASCRIPT CODE :-)

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

  162. 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
  163. return cache.addAll([ '/index.html', '/styles/main.css', '/scripts/main.js' ]); }) ); }); sw.js

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

    function(event) { // Intercept network requests }); sw.js
  165. 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
  166. THE SERVICE WORKER IS 
 INDEPENDENT OF YOUR WEBPAGE

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

    Edge (behind flag)
  168. PUSH NOTIFICATIONS

  169. WEB PUSH 
 API WEB PUSH 
 PROTOCOL SERVICE WORKERS

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

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

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

    sleeping
  174. The server has new 
 information for the user

  175. The server sends a message to the 
 push server

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

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

  178. (optional)

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

  180. The webpage is still closed and 
 the service worker

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

    Edge (behind flag)
  182. WEB PAYMENTS

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

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

    var methodData = [ { supportedMethods: ["visa", "mastercard"] } ];
  185. 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" } } };
  186. var request = new PaymentRequest( methodData, // required payment method

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

  188. Select your payment 
 method or use the default

  189. Enter your CVC code or confirm with your fingerprint

  190. Done!


  191. BROWSER SUPPORT Chrome Samsung 4 Edge (behind flag) (coming soon)

  192. BUT WHAT ABOUT 
 THE DESKTOP?

  193. BROWSER DEVELOPMENT 
 IS DRIVEN BY MOBILE

  194. None
  195. BUT…

  196. NATIVE PWA SUPPORT 
 IN THE WINDOWS STORE

  197. NATIVE PWA SUPPORT 
 IN THE WINDOWS STORE

  198. None
  199. BUT WHAT ABOUT 
 APPLE?

  200. THIS IS NOT A GOOGLE THING

  201. None
  202. BUT…

  203. ? ×

  204. THE OLD HACKS STILL WORK

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

  206. OR NOT

  207. None
  208. None
  209. None
  210. None
  211. None
  212. None
  213. None
  214. THANK YOU! @HTML5TEST

  215. PROGRESSIVE WEB APPS
 CODE LAB 
 14:00 - 15:30

  216. 18 NOVEMBER, LONDON Dylan Schiemann, Christian Heilmann, Mark Wubben, Jonathan

    Fielding
 and me