Pennapps hackathon - Workshop: Progressive Web Apps, the future of web development - University of Pennsylvania

Pennapps hackathon - Workshop: Progressive Web Apps, the future of web development - University of Pennsylvania

📹 Video: https://www.youtube.com/watch?v=de1xiqz-BTE
🔗 Twitter: https://twitter.com/JGFerreiro
🔗 Linkedin: https://www.linkedin.com/in/jgferreiro/

Progressive Web Apps is a term that Google created in 2015. Representing the next revolution in web development, PWAs enable more reliable, faster and engaging user experiences while also incorporating mobile app functionalities into websites. These and other features lead many engineers to believe that PWA’s are the future of web development.

I run this workshop in the university of Pennsylvania for Pennapps. We created a progressive web app with the following functionalities:

- Offline mode
- Caching requests: images, CSS, index.html.
- Local Notifications
- Payments Api
- How to setup your app manifest
- Add to home screen

- - -

Subscribe: https://www.ferreiro.me/newsletter

on https://www.twitter.com/jgferreiro
on https://www.linkedin.com/in/jgferreiro/
on https://www.instagram.com/jgferreiro/

523f2560aefa80575be1aff88ec240dd?s=128

Jorge Ferreiro

September 07, 2019
Tweet

Transcript

  1. Progressive Web Apps 101 Jorge Ferreiro @jgferreiro - www.ferreiro.me

  2. @JGFERREIRO @JGFERREIRO #PENNPWA Twitter increases +75% tweets sent in their

    new Progressive Web app
  3. @JGFERREIRO #PENNPWA Frontend @Eventbrite Alumni @Amazon Blogger, DJ, fan of

    musicals Jorge Ferreiro
  4. @JGFERREIRO #PENNPWA PENNAPPS MADRID "✈$

  5. @JGFERREIRO @JGFERREIRO #PENNPWA youtube.com/jgferreiro My youtube show:

  6. @JGFERREIRO @JGFERREIRO #PENNPWA Agenda 1. What, why and the industry

    2. Metadata + manifest 3. Service workers 4. Cache API 5. Web Payments 6. Local Notifications 7. Action items Important quote
  7. @JGFERREIRO @JGFERREIRO #PENNPWA #PWAPENN @JGFERREIRO

  8. @JGFERREIRO @JGFERREIRO What are we gonna build today? 0.

  9. @JGFERREIRO @JGFERREIRO #PENNPWA Our first Progressive Web App! ✅ Offline

    mode ✅ Local Notifications ✅ Cache requests ✅ Payments API ❌ Background Sync ❌ IndexedDB Emotion CSS-in-JS
  10. @JGFERREIRO @JGFERREIRO #PENNPWA github.com/ferreiro/pwa-101 ferreiro/pwa-101 Source code

  11. @JGFERREIRO @JGFERREIRO #PENNPWA Audience: Goals Experts on PWA Web devs

    with no experience on PWA Beginners
  12. @JGFERREIRO @JGFERREIRO ' What are Progressive Web Apps? 1.

  13. @JGFERREIRO #PENNPWA Progressive Web Apps (PWAs) are web applications with

    native mobile apps capabilities
  14. @JGFERREIRO @JGFERREIRO #PENNPWA Responsive ( Works offline ⚙ App-like- interactions

    Fresh Safe Discoverable Re-engageable PWA features (Alex Russell Jake Archibald) Durable Linkable Alex Russel “Progressive Web Apps: Escaping Tabs Without Losing Our Soul”
  15. @JGFERREIRO @JGFERREIRO #PENNPWA Using latest browser features when they are

    available, and adapt the user experience Progressive enhancement:
  16. @JGFERREIRO Progressive enhancement: Intuition

  17. @JGFERREIRO @JGFERREIRO #PENNPWA ๏ Simplified web version ๏ Data save

    mode ๏ Limit access to advanced features Progressive enhancement: Example ๏ High quality media ๏ Advanced Features: Push, background sync, etc. United States Bad 2G connection | Cheap phone 5G connection | High quality phones 2 Africa
  18. @JGFERREIRO @JGFERREIRO #PENNPWA Progressive enhancement: Simplification if ('feature' in browser)

    { !// Feature is available!!! !// Do something cool with it! } else { !// Party pooper !// Browser does not support this feature !// Change your browser!!... }
  19. @JGFERREIRO @JGFERREIRO Why Progressive Web Apps? 2.

  20. @JGFERREIRO @JGFERREIRO #PENNPWA Distribution Freedom No need apple store or

    play store 5 Key Benefits of Progressive Web Apps Push notifications Parity feature with Native. Re-engaging users No install required A matter of seconds to have them installed Smaller Native apps tend to occupy more space. Offline! Improves user retention and converstions. Why?
  21. @JGFERREIRO @JGFERREIRO PWAs in the industry 3.

  22. @JGFERREIRO @JGFERREIRO #PENNPWA Twitter -70% data consumption +65% increase in

    pages per session +75% increase in Tweets sent How we built Twitter Lite
  23. @JGFERREIRO @JGFERREIRO #PENNPWA Alibaba +76% conversions 4X higher interaction rate

    from Add to Homescreen https://developers.google.com/web/showcase/2016/alibaba
  24. @JGFERREIRO @JGFERREIRO #PENNPWA Starbucks +12% growth on orders w/w (May

    2018) Nearly doubled daily & monthly active users Google I/O 18’
  25. @JGFERREIRO @JGFERREIRO #PENNPWA Tinder Loading time: 11.37s to 4.69s 90%

    smaller than Android
  26. @JGFERREIRO @JGFERREIRO #PENNPWA Tinder

  27. @JGFERREIRO @JGFERREIRO #PENNPWA Pinterest A one year PWA retrospective +401%

    number of pins +103% active users y/y on mobile web +843% new signups y/y
  28. @JGFERREIRO @JGFERREIRO #PENNPWA Pinterest A one year PWA retrospective +401%

    number of pins +103% active users y/y on mobile web +843% new signups y/y
  29. @JGFERREIRO @JGFERREIRO #PENNPWA Let’s build our first PWA!

  30. @JGFERREIRO @JGFERREIRO #PENNPWA Our first Progressive Web App! Emotion CSS-in-JS

    ✅ Offline mode ✅ Local Notifications ✅ Cache requests ✅ Payments API ❌ Background Sync ❌ IndexedDB
  31. @JGFERREIRO @JGFERREIRO Progressive metatags 4.

  32. @JGFERREIRO @JGFERREIRO #PENNPWA Viewport metatag <meta name="viewport" content="width=device-width, initial-scale=1"> mdn:

    Using the viewport meta tag Forces the browser to use real device width
  33. @JGFERREIRO @JGFERREIRO #PENNPWA Theme color <meta name="theme-color" content="#fb8397">

  34. @JGFERREIRO @JGFERREIRO #PENNPWA Apple metatags Apple: Configuring web applications <meta

    name="apple-mobile-web-app-title" content="Pennapps"> <meta name="apple-mobile-web-app-status-bar-style" content="white"> <meta name="apple-mobile-web-app-capable" content="yes">
  35. @JGFERREIRO @JGFERREIRO #PENNPWA More Apple metatags… icons favicon-generator.org <link rel="apple-touch-icon"

    sizes="57x57" href=“image_57_57.png"> <link rel="apple-touch-icon" sizes="60x60" href="image_60_60.png"> <link rel="apple-touch-icon" sizes="72x72" href="image_72_72.png"> <link rel="apple-touch-icon" sizes="76x76" href="image_76_76.png"> <link rel="apple-touch-icon" sizes="114x114" href="image_114_114.png"> <link rel="apple-touch-icon" sizes="120x120" href="image_120_120.png"> <link rel="apple-touch-icon" sizes="144x144" href="image_144_144.png"> <link rel="apple-touch-icon" sizes="152x152" href="image_152_152.png"> <link rel="apple-touch-icon" sizes="180x180" href="image_180_180.png">
  36. @JGFERREIRO @JGFERREIRO Manifest.json 5.

  37. @JGFERREIRO @JGFERREIRO #PENNPWA manifest.json is a configuration file to tell

    the browser how your should behave once installed
  38. @JGFERREIRO @JGFERREIRO #PENNPWA Create manifest.json "short_name": "Pennapps", "name": "Pennapps agenda",

    "start_url": "/?utm_source=pwa", "display": "standalone", "theme_color": "#ffffff", "background_color": "#ffffff", "scope": "/", "icons": [] { } <link href="/static/manifest.json" rel="manifest">
  39. @JGFERREIRO @JGFERREIRO #PENNPWA “short_name": "Pennapps", "name": "Pennapps agenda", "start_url": "/?utm_source=pwa",

    "display": "standalone", "theme_color": "#ffffff", "background_color": "#ffffff", "scope": "/", "icons": [] { } { !// 192 for the “home screen icon” "src": "/static/images/pennapps_logo_pwa_192_192.png", "sizes": "192x192", "type": "image/png" }, { !// 512 for splash screen (on Android) "src": "/static/images/pennapps_logo_pwa_512_512.png", "sizes": "512x512", "type": "image/png" } ]
  40. @JGFERREIRO @JGFERREIRO #PENNPWA Manifest.json - display fullscreen No browser UI

    ✅ Videogames standalone Hides standard browser UI elements ✅ Standalone native app minimal-ui Fullscreen display. Minimal UI elements browser Standard browser experience Google: Web App Manifest
  41. @JGFERREIRO @JGFERREIRO #PENNPWA Test your manifest in dev tools

  42. @JGFERREIRO Test your manifest in Lighthouse

  43. @JGFERREIRO @JGFERREIRO Intro to Service Workers 6.

  44. @JGFERREIRO @JGFERREIRO #PENNPWA A service worker is a JavaScript file

    that runs separately from the main browser thread
  45. @JGFERREIRO @JGFERREIRO #PENNPWA

  46. @JGFERREIRO @JGFERREIRO Our first service worker

  47. SERVICE WORKER :: REGistering new SW if ('serviceWorker' in navigator)

    { console.log('⭐ Start to register a service worker') navigator.serviceWorker.register('/sw.js') .then((registration) !=> { console.log('SW!::Registration', registration) }) .catch((error) !=> { console.log('SW!::Error registering', error) }); }
  48. SERVICE WORKER :: INSTALL CALLBACK self.addEventListener('install', (event) !=> { !//

    Install anything you need here! })
  49. SERVICE WORKER :: FETCH CALLBACK self.addEventListener('fetch', (event) !=> { console.log('I

    am intercepting network requests!') const url = event.request.url console.log('Requested resource url: ', url) })
  50. @JGFERREIRO @JGFERREIRO #PENNPWA

  51. @JGFERREIRO @JGFERREIRO Offline mode with Cache API 7.

  52. @JGFERREIRO #PENNPWA Cache API is a key-value storage mechanism for

    requests<>responses pairs
  53. @JGFERREIRO #PENNPWA Cache API gives programmatic control over caching assets

    inside a service worker
  54. @JGFERREIRO @JGFERREIRO #PENNPWA

  55. @JGFERREIRO @JGFERREIRO Caching critical assets 7.1

  56. CACHE API :: HELLO WORLD const cacheNameVersion = 'resources-v1' caches.open(cacheNameVersion)

    .then((cache) !=> { !// Do something cool with the cache }) .catch((error) !=> { !// Error opening the cache :/ })
  57. CACHE API :: HELLO WORLD const cacheNameVersion = 'resources-v1' self.addEventListener('install',

    () !=> { caches.open(cacheNameVersion) .then((cache) !=> { !// Do something cool with the cache }) .catch((error) !=> { !// Error opening the cache :/ }) })
  58. CACHE API :: REQUIRING CRITICAL ASSETs const cacheVersion = 'version-1'

    const criticalAssets = ['/index.html', '/client.bundle.js'] self.addEventListener('install', (event) !=> { event.waitUntil(cacheAssets()) }) function cacheAssets() { return caches.open(cacheVersion) .then((cache) !=> { cacheNoCriticalAssets(cache) return cacheCriticalAssets(cache) }) } function cacheCriticalAssets (cache) { return cache.addAll(criticalAssets) } function cacheNoCriticalAssets(cache) { cache.add('./foo.css') }
  59. @JGFERREIRO @JGFERREIRO #PENNPWA event.waitUntil Service worker will stay in “install”

    mode, until waitUntil is resolved
 If the resolved promise fails, it will not install anything…
  60. @JGFERREIRO @JGFERREIRO #PENNPWA Check cached resources

  61. @JGFERREIRO @JGFERREIRO #PENNPWA Check cached resources

  62. @JGFERREIRO @JGFERREIRO #PENNPWA Check cache size

  63. @JGFERREIRO @JGFERREIRO Removing old cache resources 7.2

  64. @JGFERREIRO @JGFERREIRO #PENNPWA

  65. CACHE API :: REMOVING CACHED ASSETS self.addEventListener('install', (event) !=> {

    !// Add assets to the service worker cache }) self.addEventListener('activated', (event) !=> { !// Remove cached assets from previous version }) Make sure to remove cached ASSETS!
  66. @JGFERREIRO @JGFERREIRO Fetch image or placeholder 7.3

  67. CACHE API :: Fetch image or placeholder self.addEventListener('fetch', (event) !=>

    { const acceptHeader = event.request.headers.get('accept') if (acceptHeader.includes('image')) { return event.respondWith( fetchImageOrPlaceholder(event) ) } })
  68. CACHE API :: Fetch image or placeholder function fetchImageOrPlaceholder(fetchEvent) {

    return fetch(fetchEvent.request, { mode: 'no-cors' }) .then((response) !=> { if (!response.ok) { throw Error(‘Can not download from server…’) } return response }) .catch(() !=> { !// NB: Return placeholder. return caches.match(PLADEHOLDER_IMAGE, { cacheName: cacheVersion }) }) }
  69. CACHE API :: Fetch image or placeholder function fetchImageOrPlaceholder(fetchEvent) {

    return fetch(fetchEvent.request, { mode: 'no-cors' }) .then((response) !=> { if (!response.ok) { throw Error(‘Can not download from server…’) } return response }) .catch(() !=> { !// NB: Return placeholder. return caches.match(PLADEHOLDER_IMAGE, { cacheName: cacheVersion }) }) }
  70. @JGFERREIRO @JGFERREIRO Network with cache backup 7.4

  71. CACHE API :: Fetch image or placeholder self.addEventListener('fetch', (event) !=>

    { const acceptHeader = event.request.headers.get('accept') if (acceptHeader.includes('image')) { return event.respondWith( fetchImageOrPlaceholder(event) ) } })
  72. CACHE API :: Fetch image or placeholder function fetchImageOrFallback(fetchEvent) {

    return fetch(fetchEvent.request, {mode: ‘no-cors’}) READ CacheStorage .then((response) !=> { if (!response.ok) { throw Error('Can not download image from server') } caches.open(cacheVersion).then(function(cache) { !// Cache in background cache.put(fetchEvent.request, response) }) return response.clone() !// NB: We can't reuse responses twice }) .catch(() !=> { return caches.match(fetchEvent.request).catch(function() { !// try to get cached return caches.match(PLADEHOLDER_IMAGE, { !// Return placeholder cacheName: cacheVersion }) }) }) }
  73. @JGFERREIRO @JGFERREIRO #PENNPWA Further reading:

  74. @JGFERREIRO @JGFERREIRO Web Payments API 8.

  75. @JGFERREIRO @JGFERREIRO #PENNPWA

  76. Web payments api :: REQUEST OBJECT const request = new

    PaymentRequest(methods, details, options) PAYMENT REQUEST CONSTRUCTOR const methods = [{ supportedMethods: 'basic-card', data: { supportedNetworks: [ 'visa', 'mastercard' ] } }] const details = { displayItems: [{ label: 'Computer to mine bitcoin', amount: { currency: 'USD', value: 1000 } }], total: { label: 'Total due', amount: { currency: tickets.currency, value : 1000 } } } const options = { !// requestPayerPhone, requestShipping, shippingType requestPayerEmail: true, requestPayerName: true, }
  77. Web payments api const request = new PaymentRequest(methods, details, options)

    PAYMENT REQUEST DEMO !// Add event listeners on user actions. Eg: shippingaddresschange paymentRequest.addEventListener( 'paymentmethodchange', handlePaymentChange, false ) paymentRequest.addEventListener( ‘shippingaddresschange', handleShippingAddressChange, false ) request.show().then(response !=> { !// [process payment] !// Send to a Payment service provider (PWA), metrics, etc response.complete('success') }).catch((error) !=> {!/* Notify user on the error !*/})
  78. @JGFERREIRO @JGFERREIRO #PENNPWA https://developers.google.com/web/fundamentals/payments/

  79. @JGFERREIRO @JGFERREIRO Local notifications 9.

  80. @JGFERREIRO @JGFERREIRO #PENNPWA

  81. CACHE API :: HELLO WORLD export const launchNotification = ({artistId,

    isEnabled}) !=> { if ('Notification' in window) { Notification.requestPermission().then((permission) !=> { const artist = artists[artistId] const title = isEnabled ? `✅ Notifications for ${artist.name} are activated!` : `❌ Deactivate ${artist.name} notifications!` const options = { body: 'You will be notified for this event', icon: '/images/pennapps_logo_pwa_192_192.png', } }) } } new Notification(title, options)
  82. @JGFERREIRO @JGFERREIRO #PENNPWA Advanced topics: Web Push Notifications: Timely, Relevant,

    and Precise Web Push Notifications through VAPID method
  83. @JGFERREIRO @JGFERREIRO App shell model 10.

  84. @JGFERREIRO #PENNPWA The app "shell" is the minimal HTML, CSS

    and JavaScript required to power the user interface
  85. @JGFERREIRO @JGFERREIRO https://developers.google.com/web/fundamentals/architecture/app-shell

  86. @JGFERREIRO @JGFERREIRO #PENNPWA

  87. @JGFERREIRO - jorge@ferreiro.me Q&A!

  88. @JGFERREIRO @JGFERREIRO #PENNPWA Who to follow? Jake Archibald Google @jaffathecake

    Alex Russell Chrome Team @slightlylate Sarah Clark Google @a_bowl_of_stars Pete LePage Google @petele Dominick Ng Chrome PWA @dominickng Scott Domes Indeed @scottdomes Kenneth C. Intel @kennethrohde Henrik Joreteg Consultant @HenrikJoreteg Charlie Croom Twitter @CharlieCroom Monica Dinculescu Polymer @notwaldorf
  89. @JGFERREIRO @JGFERREIRO #PENNPWA Action items 1. Fork “pwa 101” repo

    and start it locally 2. Re-read this presentation, and open some of the links in the resources 3. Execute each of the steps to add progressive enhancement to your app
  90. @JGFERREIRO @JGFERREIRO #PENNPWA Research on advanced topics: 1. Background sync

    2. IndexedDB 3. Push notifications with Web Push 4. HTTP2 Action items (II)
  91. @JGFERREIRO @JGFERREIRO #PENNPWA Resources 1. Google I/O 2014 - Bridging

    the gap between the web and apps 2. How we built Twitter Lite 3. Twitter Lite and High Performance React Progressive Web Apps at Scale 4. Google workbox 5. Payment request 6. Frontend masters: Progressive web apps 7. Background sync 8. Google: Progressive web apps YouTube traiing
  92. @JGFERREIRO @JGFERREIRO #PENNPWA One more thing…

  93. @JGFERREIRO @JGFERREIRO #PENNPWA ✅ T-shirt Eventbrite ✅ T-shirt "DevelopersInDepth" (DID)

    ✅ 1h pair programming session / coaching session with me ✅ Eventbrite stickers + DID stickers ✅ Badge "Best PWA in Pennapps" Pennapps PWA Contest bit.ly/pwa-contest
  94. @JGFERREIRO #PENNPWA PWA are the future of mobile apps. Start

    learning today
  95. Thanks #pennapps! @jgferreiro jorge@ferreiro.me