@AaronGustafson
What’s a PWA, technically?
HTTPS
Web App Manifest
Service Worker
Slide 16
Should I believe the hype?
Slide 17
Maybe?
Slide 18
Starbucks: 2x increase in daily active users
aka.ms/google-io-2018
Slide 19
Tinder: Core experience with 90% less code
aka.ms/tinder-pwa-2017
Slide 20
Trivago: 97% increase in click-outs to hotel offers
aka.ms/trivago-pwa-2017
Slide 21
West Elm: 15% increase in time on site 9% increase in revenue per visit
aka.ms/west-elm-pwa-2017
Slide 22
Slide 23
@AaronGustafson
Let’s talk about Service Worker
Slide 24
@AaronGustafson
Registering a Service Worker if ( “serviceWorker” in navigator ) { navigator.serviceWorker.register( “/serviceworker.min.js” ); }
h t a P
p m is i
! t n a t or
Slide 25
@AaronGustafson
The Service Worker Lifecycle Browser
Install
Activation
aka.ms/pwa-lifecycle
Ready
Slide 26
@AaronGustafson
How connections are made Browser
Internet
Slide 27
@AaronGustafson
Along comes Service Worker Browser
Cache
Internet
Slide 28
@AaronGustafson
Along comes Service Worker Browser
! Cache
Internet
Slide 29
PWAs start with a great web experience and then enhance that experience for performance, resilience, installation, and engagement
Slide 30
Progressive Web App Enhancement
Slide 31
PWAs start with a great web experience and then enhance that experience for performance, resilience, installation, and engagement
Slide 32
Progressive Web App
Slide 33
Progressive /prəˈɡresiv/
happening or developing gradually or in stages; proceeding step by step
Slide 34
Patrick Perkins
Slide 35
Consider forbes.com circa 2007 @AaronGustafson
Slide 36
“Mobile first” thinking isn’t just about mobile
Slide 37
Patrick Perkins
Slide 38
Patrick Perkins
Slide 39
Step 2
Use markup that supports the core experience
Avinash Arunachalam AM Patrick Perkins
Slide 40
Avinash Arunachalam A M
Slide 41
@AaronGustafson
What does it mean? <div class=”entry”> <div class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</div> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </div>
Slide 42
@AaronGustafson
This is self-contained content <div class=”entry”> <div class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</div> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </div>
Slide 43
@AaronGustafson
There’s a tag for that: article <article class=”entry”> <div class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</div> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 44
@AaronGustafson
This is the title of the post <article class=”entry”> <div class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</div> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 45
@AaronGustafson
There’s a tag for that: h1-h6 <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 46
@AaronGustafson
Various properties of the post <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <div class=”entry__meta”> <div><b>Published</b> 24 May 2017</div> <div><b>Reading Time</b> 25 minutes</div> </div> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 47
@AaronGustafson
There’s an element for that: dl <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <dl class=”entry__meta”> <dt>Published</dt> <dd>24 May 2017</dd> <dt>Reading Time</dt> <dd>25 minutes</dd> </dl> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 48
@AaronGustafson
Bonus: time <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <dl class=”entry__meta”> <dt>Published</dt> <dd><time>24 May 2017</time></dd> <dt>Reading Time</dt> <dd>25 minutes</dd> </dl> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 49
@AaronGustafson
Bonus: time <time datetime=”2017-05-24”> 24 May 2017</time> <time datetime=”2017-05-24T11:13:24”> 24 May 2017</time> <time datetime=”2017-05-24T11:13:24-04:00”> 24 May 2017</time>
Slide 50
@AaronGustafson
“Flow” content with line breaks <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <dl class=”entry__meta”> <dt>Published</dt> <dd><time …>24 May 2017</time></dd> <dt>Reading Time</dt> <dd>25 minutes</dd> </dl> <div class=”entry__content”> I had the great pleasure of delivering a talk… <br><br> I do a lot of traveling and it’s… </div> </article>
Slide 51
@AaronGustafson
“Flow” content, divided <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <dl class=”entry__meta”> <dt>Published</dt> <dd><time …>24 May 2017</time></dd> <dt>Reading Time</dt> <dd>25 minutes</dd> </dl> <div class=”entry__content”> <div>I had the great pleasure of delivering a…</div> <div>I do a lot of traveling and it’s…</div> </div> </article>
Slide 52
@AaronGustafson
This is meaningful content <article class=”entry”> <h1 class=”entry__title”>Progressive Web Apps and the Windows Ecosystem</h1> <dl class=”entry__meta”> <dt>Published</dt> <dd><time …>24 May 2017</time></dd> <dt>Reading Time</dt> <dd>25 minutes</dd> </dl> <div class=”entry__content”> <p>I had the great pleasure of delivering a talk…</p> <p>I do a lot of traveling and it’s…</p> </div> </article>
Slide 53
Avinash Arunachalam A M
Slide 54
@AaronGustafson
Readability
Slide 55
Slide 56
Hey Cortana, read me the top three headlines in today’s New York Times
Slide 57
@AaronGustafson
Access via semantics: function extractHeadlines( response ){ var $html = document.createElement(‘div’), $headings, i=0, headlines=[]; $html.innerHTML = response.contents; $headings = $html.querySelector(‘#top-new’) .querySelectorAll(‘article h1, article h2, article h3’); heading_count = $headings.length; while (headlines.length < 3) { let $link = $headings[i].querySelector(‘a’); if ($link && $link.href) { headlines.push({ title: $headings[i].innerText.trim(), link: $link.href }); } i++; } console.log( headlines ); }
Slide 58
@AaronGustafson
Access via semantics: function extractHeadlines( response ){ var $html = document.createElement(‘div’), $headings, i=0, headlines=[]; $html.innerHTML = response.contents; $headings = $html.querySelector(‘#top-new’) .querySelectorAll(‘article h1, article h2, article h3’); heading_count = $headings.length; while (headlines.length < 3) { let $link = $headings[i].querySelector(‘a’); if ($link && $link.href) { headlines.push({ title: $headings[i].innerText.trim(), link: $link.href }); } i++; } console.log( headlines ); }
Slide 59
More about semantics for “headless” UIs
aka.ms/conversational-semantics
Slide 60
aka.ms/dependency-awareness
Slide 61
@AaronGustafson
Let’s say you needed a button… <input type=”submit” value=”Sign Up”>
Sign Up
<button type=”submit”>Sign Up</button> <a class=”button” href=”#”>Sign Up</a> <div class=”button”>Sign Up</div>
Slide 62
@AaronGustafson
Let’s compare Pattern
input[type=submit]
button[type=submit]
a
div
Display
button
Semantics
button
Focusable?
Activate By
Submits Forms
Yes
Mouse, touch, ENTER, SPACE
Yes
Yes
Mouse, touch, ENTER, SPACE
Yes
No
No
button
button
link
Named generic
Yes
Mouse, touch, ENTER
block
Not exposed
No
N/A
Slide 63
@AaronGustafson
UX gaps that need to be filled Pattern
input[type=submit]
button[type=submit]
a
div
Display
button
Semantics
button
Focusable?
Activate By
Submits Forms
Yes
Mouse, touch, ENTER, SPACE
Yes
Yes
Mouse, touch, ENTER, SPACE
Yes
No
No
button
button
link
Named generic
Yes
Mouse, touch, ENTER
block
Not exposed
No
N/A
Slide 64
@AaronGustafson
Moar dependencies Pattern
Display
Semantics
Focusable?
Activate By
Submits Forms
input[type=submit]
None
None
None
None
None
button[type=submit]
None
None
None
None
None
a
CSS
ARIA
None
JavaScript
JavaScript
div
CSS
ARIA
HTML
JavaScript
JavaScript
Slide 65
@AaronGustafson
Moar dependencies Pattern
Display
Semantics
Focusable?
Activate By
Submits Forms
input[type=submit]
None
None
None
None
None
button[type=submit]
None
None
None
None
None
a
CSS
ARIA
None
JavaScript
JavaScript
div
CSS
ARIA
HTML
JavaScript
JavaScript
Slide 66
@AaronGustafson
Potential for failure
Moar dependencies, moar (potential) problems
Dependencies
Slide 67
@AaronGustafson
Disaster averted
Slide 68
@AaronGustafson
Potential for failure
Moar dependencies, moar (potential) problems
Dependencies
Slide 69
@AaronGustafson
User Experience
Enhance the experience
Capabilities
@AaronGustafson
Enhancing UX with markup <input type=”email” name=”email” id=”email” required aria-required=”true”>
Experience deltas 1. Support for email input type? 2. Validation algorithm implemented? 3. Virtual keyboard?
Slide 72
@AaronGustafson
Enhancing UX with markup <input type=”email” name=”email” id=”email” required aria-required=”true”>
Experience deltas 1. Support for HTML validation?
Slide 73
@AaronGustafson
Enhancing UX with markup <input type=”email” name=”email” id=”email” required aria-required=”true”>
Experience deltas 1. Browser exposure of aria-required property? 2. Assistive tech implementation of aria-required?
Slide 74
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 75
Avinash Arunachalam A M
Slide 76
Step 3
Design in support of the core experience
Avinash Arunachalam AM Chris Grafton
Slide 77
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 78
aka.ms/enhanced-css-layouts
Slide 79
Good design is problem solving. — Jeff Veen
Slide 80
@AaronGustafson
Tools for graphic design Alignment
Proportion
Balance
Proximity
Contrast
Repetition
Emphasis
Rhythm
Gestalt
Unity
Harmony
White Space
Movement
Slide 81
@AaronGustafson
Tools for graphic design Alignment
Proportion
Balance
Proximity
Contrast
Repetition
Emphasis
Rhythm
Gestalt
Unity
Harmony
White Space
Movement
Slide 82
@AaronGustafson
Alignment
Slide 83
@AaronGustafson
Contrast
Slide 84
@AaronGustafson
Proportion
Slide 85
@AaronGustafson
Proximity
Slide 86
@AaronGustafson
Rhythm
aka.ms/vertical-rhythm
Slide 87
@AaronGustafson
Unity
Slide 88
@AaronGustafson
Unique design considerations Screen size Resolution Brightness Color density User preference Network speed & quality Assistive technology
Slide 89
@AaronGustafson
Unique design considerations Screen size Resolution Brightness Color density User preference Network speed & quality Assistive technology
☞ ☞ ☞ ☞ ☞
Slide 90
@AaronGustafson
Unique design considerations Screen size Resolution Brightness Color density User preference Network speed & quality Assistive technology
Don’t rely on color alone to convey important information
Confirm
Cancel
Confirm
Cancel
Slide 94
Good contrast ensures your content is readable
aka.ms/color-contrast
Slide 95
Explicit connections ensure everyone can follow references
Slide 96
Explicit connections ensure everyone can follow references
<a href=”#figure-3-3”>Figure 3.3</a> shows the lodging article in Safari with only the default browser styles applied. …
<figure id=”figure-3-3”> … </figure>
Slide 97
Slide 98
Consider what your design leaves unsaid
Slide 99
Consider what your design leaves unsaid
aria-label=”You can finish reading “The Web Should Just Work for Everyone” in less than 10 minutes”
Slide 100
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 101
@AaronGustafson
Enhancing design in CSS p { color: green; color: rgba(0, 255, 0, .8); }
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 102
@AaronGustafson
Enhancing design in CSS p { color: green; color: rgba(0, 255, 0, .8); }
Older browsers without RGBa support, ignore the second rule
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 103
@AaronGustafson
Enhancing design in CSS p { color: green; color: rgba(0, 255, 0, .8); }
Modern browsers with RGBa support, overwrite the first rule
Slide 104
@AaronGustafson
Enhancing design in CSS h1:has(+ p) { color: green; }
(That selects h1s that have adjacent sibling paragraphs.)
Passwords can be a hassle Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 105
@AaronGustafson
Enhancing design in CSS h1:has(+ p) { color: green; }
Browsers that don’t support :has() ignore the entire rule set
Passwords can be a hassle Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 106
@AaronGustafson
Beware the comma! div:hover .extra-stuff, div:focus-within .extra-stuff { /* reveal it */ }
Slide 107
@AaronGustafson
Beware the comma! div:hover .extra-stuff, div:focus-within .extra-stuff { /* reveal it */ }
Browsers that don’t support :focus-within
Slide 108
@AaronGustafson
Beware the comma! div:hover .extra-stuff, div:focus-within .extra-stuff { /* reveal it */ }
Browsers that do support :focus-within
Slide 109
@AaronGustafson
Enhancing design in CSS h1:has(+ p) { color: green; }
As browsers support :has(), matching h1s will turn green
Passwords can be a hassle Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 110
@AaronGustafson
Enhancing design in CSS @media only screen { p { color: green; } }
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 111
@AaronGustafson
Enhancing design in CSS @media only screen { p { color: green; } }
Browsers without media query support ignore the block
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 112
@AaronGustafson
Enhancing design in CSS @media only screen { p { color: green; } }
Browsers with media query support apply it
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 113
@AaronGustafson
Enhancing design in CSS @supports (display: grid) { p { color: green; } }
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 114
@AaronGustafson
Enhancing design in CSS @supports (display: grid) { p { color: green; } }
Browsers that don’t grok @supports ignore the block
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 115
@AaronGustafson
Enhancing design in CSS @supports (display: grid) { p { color: green; } }
Browsers that understand @supports, but don’t support grid ignore it
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 116
@AaronGustafson
Enhancing design in CSS @supports (display: grid) { p { color: green; } }
Browsers that understand @supports and grid apply it
Passwords can be a hassle. Most people don’t create strong passwords or make sure to maintain a different one for every site. People create easy-to-remember passwords and typically use the same passwords across all of their accounts.
Slide 117
Chris Grafton
Slide 118
Chris Grafton
Slide 119
aka.ms/enhanced-css-layouts
Slide 120
@AaronGustafson
User Experience
Enhance the experience
Capabilities
@AaronGustafson
Also “mobile first” ๏
Selectively deliver advances styles
๏
Isolate large CSS images in min-width media queries
๏
Don’t hide content images using CSS
๏
Use responsive images
๏
Prefer system fonts
๏
font-display: optional
Slide 128
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 129
Step 4
Improve the core experience with JavaScript
ChrisCreswick Grafton Jacob
Slide 130
Jacob Creswick
Slide 131
Jacob Creswick
Slide 132
@AaronGustafson
Got let? document.body.innerHTML += ‘<p>Can I count to four?</p>’; for ( let i=1; i<=4; i++ ) { document.body.innerHTML += ‘<p>’ + i + ‘</p>’; } document.body.innerHTML += ‘<p>Success!</p>’;
Slide 133
aka.ms/js-let-down
Slide 134
aka.ms/js-let-down
Slide 135
@AaronGustafson
Potential for failure
Moar dependencies, moar (potential) problems
Dependencies
Slide 136
aka.ms/github-removes-jquery
Slide 137
As part of our refined approach to building frontend features on GitHub.com, we focused on getting away with regular HTML foundation as much as we could, and only adding JavaScript behaviors as progressive enhancement. As a result, even those web forms and other UI elements that were enhanced using JS would usually also work with JavaScript disabled in the browser.
aka.ms/github-removes-jquery
Slide 138
As part of our refined approach to building frontend features on GitHub.com, we focused on getting away with regular HTML foundation as much as we could, and only adding JavaScript behaviors as progressive enhancement. As a result, even those web forms and other UI elements that were enhanced using JS would usually also work with JavaScript disabled in the browser.
aka.ms/github-removes-jquery
Slide 139
Jacob Creswick
Slide 140
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 141
Slide 142
@AaronGustafson
Detecting support if ( navigator.credentials ) { // Actual logic goes here }
Slide 143
@AaronGustafson
User Experience
Enhance the experience
Capabilities
Slide 144
Jacob Creswick
Slide 145
@AaronGustafson
Registering a Service Worker if ( navigator.serviceWorker ) { navigator.serviceWorker.register(‘/serviceworker.js’) .then(function(registration) { console.log(‘Success!’, registration.scope); }) .catch(function(error) { console.error(‘Failure!’, error); }); }