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.
@joshholmes
Performant
PWAs
Josh Holmes
josh.holmes@microsoft.com
@joshholmes
@joshholmes
Microsoft Edge and Chromium Open
Source: Our Intent
1. We will adopt Chromium as the web platform for Microsof...
@joshholmes
A.K.A. “PWA”
@joshholmes
PROGRESSIVE WEB APP
@joshholmes
Game
Gallery
Book
Newspaper
Art Project
Tool
PROGRESSIVE WEB APP
@joshholmes
PROGRESSIVE WEB SITE
@joshholmes
PROGRESSIVE WEB SITE++
@joshholmes
PROGRESSIVE WEB SITE++
HTTPS
Manifest.json
ServiceWorker.js
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
PWA IS
@joshholmes
https://www.pwabuilder.com/
@joshholmes
{"dir" : "ltr",
"lang" : "en",
"name" : "Twitter",
"scope" : "/",
"display" : "standalone",
"start_url" : "htt...
@joshholmes
//Install stage sets up the offline page in the cache and opens a new cache
self.addEventListener('install', f...
@joshholmes
//Add this below content to your HTML page, or add the js file to your page at the very top to register servic...
@joshholmes
/ˈfrikSH(ə)n/
@joshholmes
Poor performance
is friction
@joshholmes
Source: eMarketer
@joshholmes
Source: eMarketer
Which of
these matter
to your
context…
Always
measure
what
matters…
@joshholmes
A 1s delay in page
load can reduce
conversions by 7%
Source: Kissmetrics
@joshholmes
For an online shop earning
$100k/day, that’s about
$2.5m in lost sales
Source: Kissmetrics
@joshholmes
For Amazon, 1s is worth
about $1.6b in sales
Source: HubSpot
@joshholmes
Source: eMarketer
@joshholmes
53% abandon
websites that take
more than 3s to load
Source: Google
@joshholmes
By shaving 7s off load,
Edmunds increased
page views by 17%
& ad revenue by 3%
Source: HubSpot
@joshholmes
Mozilla reduced page load
by 2.2s and saw a 15.4%
increase in downloads
Source: HubSpot
@joshholmes
Performance
matters
@joshholmes
/dôɡˈfo͞odiNG/
@joshholmes
Let’s talk (briefly)
about page load
@joshholmes
time
Your Device The Web
DNS Lookup
Icons by Mahmure Alp
@joshholmes
time
Your Device The Web
TCP Handshake
Icons by Mahmure Alp
@joshholmes
time
Your Device The Web
Request
Icons by Mahmure Alp
@joshholmes
time
Your Device The Web
Server Processing
Icons by Mahmure Alp
@joshholmes
time
Your Device The Web
Response
Icons by Mahmure Alp
@joshholmes
Icons by Mahmure Alp
@joshholmes
WEB RUNTIME
ARCHITECTURE
@joshholmes
WEB RUNTIME ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 7...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
WEB PLATFORM ARCHITECTURE
Networking /
Cache
Parsers
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout Painting
1
2 ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
DOM Parsing
<html>
<head>
<title>Silly example</title>
<script src="head.js"></script>
<link rel="stylesheet" ...
@joshholmes
Steps for better performance
1. Use native features whenever possible
2. Only include assets you actually need...
@joshholmes
Step 1:
Use native features
whenever possible
@joshholmes
(they’re effectively free)
@joshholmes
Por exemplo
<header>
Header content…
</header>
@joshholmes
Por exemplo
<input id="n" name="n"
required aria-required="true"
autocorrect="off"
autocapitalize="words"
plac...
@joshholmes
Por exemplo
<input type="email"
id="e" name="e"
required aria-required="true"
autocorrect="off"
autocapitalize...
@joshholmes
Por exemplo
@media (min-width:600px) {
.gridded {
display: grid;
grid-template-columns: 1fr 300px;
grid-gap: 2...
@joshholmes
Step 2:
Only include assets
you actually need
@joshholmes
Great tools,
possibly overkill
@joshholmes
Every tool has a cost
Framework Size (Compressed)
Bootstrap 2 149 kB
Bootstrap 3 103 kB
Angular 1.4 51 kB
Embe...
@joshholmes
Chances are, your
library of choice
is on a CDN
@joshholmes
time
Your Device The Web
Icons by Mahmure Alp
@joshholmes
time
Your Device The Web
Icons by Mahmure Alp
You can optimize this
@joshholmes
Find the server early
<link rel="prefetch"
href="https://cdn.foo.com">
@joshholmes
time
Your Device The Web
Icons by Mahmure Alp
You can optimize this
@joshholmes
Go for the handshake
<link rel="preconnect"
href="https://cdn.foo.com">
@joshholmes
time
Your Device The Web
Icons by Mahmure Alp
You can even optimize this
@joshholmes
Grab that resource
<link rel="preload"
href="https://cdn.foo.com/jquery.min.js"
as="script">
@joshholmes
Download isn’t everything
Source: The Filament Group
@joshholmes
Download isn’t everything
Framework Method/function operations/s
Vanilla JS document.getElementById() 12,137,2...
@joshholmes
@joshholmes
We used some hints though
<link rel="preconnect"
href="//10kapart.blob.core.windows.net">
<link rel="preconnec...
@joshholmes
Step 3:
Optimize
everything
@joshholmes
Our approach to CSS (Gulp)
1. Write modular CSS in Sass (+ Breakup for MQ management)
2. Compile CSS with a pr...
@joshholmes
Before
@joshholmes
After
@joshholmes
Our approach to JS (Gulp)
1. Write modular JavaScript, grouped as appropriate
2. Combine files based on folder...
@joshholmes
Results
about 8 kB all-up
@joshholmes
Interesting side note
@joshholmes
We also minified
& pre-compressed
our HTML
@joshholmes
Step 4:
Think about when
you load assets
@joshholmes
We had 10 JS files
๏ Global
‣ main.js - the site’s library
‣ serviceworker.js - The site’s service worker
๏ Br...
@joshholmes
We had 10 JS files
๏ Page-specific
‣ enter.js - Entry form-related code
‣ form-saver.js - Used to save form en...
@joshholmes
Per the common wisdom
<script src="/j/main.min.js"></script>
</body>
</html>
@joshholmes
No need to run immediately
<script src="/j/main.min.js"></script>
<script src="/j/home.min.js"
defer
></script...
@joshholmes
Run whenever you can
<script src="/j/main.min.js"></script>
<script src="/j/home.min.js"
async
></script>
</bo...
@joshholmes
Consider dependencies
<script src="/j/main.min.js"></script>
<script src="/j/home.min.js" async></script>
@joshholmes
Consider dependencies
<script src="/j/main.min.js" async></script>
<script src="/j/home.min.js" async></script>
@joshholmes
“race condition”
@joshholmes
Avoid race conditions
<script src="/j/main.min.js"></script>
<script src="/j/home.min.js" async></script>
@joshholmes
Why so many
separate files?
@joshholmes
Connections in HTTP/1.1
Browser Per host Overall
IE 9 6 35
IE 10 8 17
IE 11 13 17
Firefox 4+ 6 17
Opera 11+ 6 ...
@joshholmes
time
Your Device The Web
HTTP/1.1
Icons by Mahmure Alp
@joshholmes
HTTP/2 creates
a single connection and
contents stream in
@joshholmes
time
Your Device The Web
HTTP/2
Icons by Mahmure Alp
@joshholmes
Source: A List Apart
@joshholmes
Demo: Akamai
@joshholmes
Source: A List Apart
@joshholmes
Step 5:
Consider how
you load assets
@joshholmes
Start simple
<link rel="stylesheet" href="/c/d.min.css">
<link rel="stylesheet" href="/c/a.min.css"
media="onl...
@joshholmes
Fault tolerance FTW!
<link rel="stylesheet" href="/c/d.min.css">
<link rel="stylesheet" href="/c/a.min.css"
me...
@joshholmes
Conditional scripting
<!--[if lt IE 9]>
<script src="/j/html5shiv.min.js"></script>
<![endif]-->
@joshholmes
Conditional scripting
<!--[if gt IE 8]><!-->
<script src="/j/main.min.js"></script>
<script src="/j/home.min.j...
@joshholmes
Conditional imagery
@joshholmes
Conditional images
@media (min-width: 36.375em) {
.presented-by [href*=microsoft]::before {
background-image: ...
@joshholmes
Conditional images
@media (min-width: 36.375em) {
.presented-by [href*=microsoft]::before {
background-image: ...
@joshholmes
Conditional images
@media (min-width: 36.375em) {
.presented-by [href*=microsoft]::before {
background-image: ...
@joshholmes
Conditional images
@media (min-width: 36.375em) {
.presented-by [href*=microsoft]::before {
background-image: ...
@joshholmes
Conditional animation
@joshholmes
How do we get there?
JS?
No
No imageLoad
Yes
<>
SVG support?
Yes
SVG
Ajax request SVG
Yank out script & add to...
@joshholmes
Step 6:
Only load assets
when they add value
@joshholmes
@joshholmes
@joshholmes
Evaluate images case-by-case
๏ Does the image reiterate information found in the surrounding text?
๏ Is the im...
@joshholmes
53% of the average web page
Source: Internet Archive
@joshholmes
And they don’t always fit
@joshholmes
Source: The Outline
@joshholmes
If you can avoid
using an image, do it
@joshholmes
If you need an image,
choose the best format
@joshholmes
Quick format recap
๏ GIF
‣ for images with large swaths of solid colors
‣ Binary transparency
๏ JPG
‣ For phot...
@joshholmes
Quick format recap
๏ PNG (8-Bit)
‣ Alternative to GIF
‣ Can support alpha transparency (with the right creatio...
@joshholmes
Quick format recap
๏ WebP
‣ Newer format, not universally supported
‣ Smaller than JPGs and 24-bit PNGs
‣ Supp...
@joshholmes
Sometimes images
are “nice to have”
@joshholmes
@joshholmes
@joshholmes
Oh wait…
optimize everything
@joshholmes
@joshholmes
@joshholmes
Source: 38 kB JPG
@joshholmes
B&W: 35 kB JPG (-7%)
@joshholmes
Crop & Resize: 12 kB JPG (-68%)
@joshholmes
Blur & optimize: 9 kB JPG (-76%)
@joshholmes
@joshholmes
WebP: 4 kB (-89%)JPG: 9 kB (-76%)
@joshholmes
Steps for better performance
1. Use native features whenever possible
2. Only include assets you actually need...
@joshholmes
https://webhint.io
@joshholmes
Every choice we
make affects our
users’ experiences
@joshholmes
Let’s spend our time to
save it for our users
@joshholmes
Speedy performance is
a great user experience
@joshholmes
Performant
PWAs
Josh Holmes
josh.holmes@microsoft.com
Prochain SlideShare
Chargement dans…5
×

1

Partager

Télécharger pour lire hors ligne

High Performance PWAs

Télécharger pour lire hors ligne

Your users deserve a fast and responsive web app and PWAs help you step that up a notch through notifications, offline support and more.

There’s a lot that goes into that from understanding how the DOM tree works and how that plays with CSS and JavaScript to how to leverage the ServiceWorker for cashing and push notifications.

In this session, we’ll build a PWA that show cases many of the things you need to keep in mind when building a great and fast progressive web app.

High Performance PWAs

  1. 1. @joshholmes Performant PWAs Josh Holmes josh.holmes@microsoft.com
  2. 2. @joshholmes
  3. 3. @joshholmes Microsoft Edge and Chromium Open Source: Our Intent 1. We will adopt Chromium as the web platform for Microsoft Edge desktop. 2. We will evolve the Microsoft Edge app architecture, enabling distribution to all supported versions of Windows including Windows 7 and Windows 8, as well as Windows 10. We will also bring Microsoft Edge to other desktop platforms, such as macOS. 3. We will offer our Windows platform expertise to improve the experience of all Chromium-based browsers on Windows. https://github.com/MicrosoftEdge/MSEdge
  4. 4. @joshholmes A.K.A. “PWA”
  5. 5. @joshholmes PROGRESSIVE WEB APP
  6. 6. @joshholmes Game Gallery Book Newspaper Art Project Tool PROGRESSIVE WEB APP
  7. 7. @joshholmes PROGRESSIVE WEB SITE
  8. 8. @joshholmes PROGRESSIVE WEB SITE++
  9. 9. @joshholmes PROGRESSIVE WEB SITE++ HTTPS Manifest.json ServiceWorker.js
  10. 10. @joshholmes PWA IS
  11. 11. @joshholmes PWA IS
  12. 12. @joshholmes PWA IS
  13. 13. @joshholmes PWA IS
  14. 14. @joshholmes PWA IS
  15. 15. @joshholmes PWA IS
  16. 16. @joshholmes PWA IS
  17. 17. @joshholmes PWA IS
  18. 18. @joshholmes PWA IS
  19. 19. @joshholmes PWA IS
  20. 20. @joshholmes PWA IS
  21. 21. @joshholmes https://www.pwabuilder.com/
  22. 22. @joshholmes {"dir" : "ltr", "lang" : "en", "name" : "Twitter", "scope" : "/", "display" : "standalone", "start_url" : "https://m.twitter.com/", "short_name" : "Twitter", "theme_color" : "#ffffff", "description" : "", "orientation" : "any", "background_color" : "transparent", "related_applications" : "", "prefer_related_applications" : "false", "icons" : [ { "src": "https://abs.twimg.com/responsive- web/web/icon-ios.8ea219d08eafdfa4.png", "sizes": "192x192" } ]} Manifest.json
  23. 23. @joshholmes //Install stage sets up the offline page in the cache and opens a new cache self.addEventListener('install', function(event) { var offlinePage = new Request('offline.html'); event.waitUntil( fetch(offlinePage).then(function(response) { return caches.open('pwabuilder-offline').then(function(cache) { console.log('[PWA Builder] Cached offline page during Install'+ response.url); return cache.put(offlinePage, response); }); })); }); //If any fetch fails, it will show the offline page. self.addEventListener('fetch', function(event) { event.respondWith( fetch(event.request).catch(function(error) { console.error( '[PWA Builder] Network request Failed. Serving offline page ' + error ); return caches.open('pwabuilder-offline').then(function(cache) { return cache.match('offline.html'); }); } )); }); //This is a event that can be fired from your page to tell the SW to update the offline page self.addEventListener('refreshOffline', function(response) { return caches.open('pwabuilder-offline').then(function(cache) { console.log('[PWA Builder] Offline page updated from refreshOffline event: '+ response.url); return cache.put(offlinePage, response); }); }); Service Worker
  24. 24. @joshholmes //Add this below content to your HTML page, or add the js file to your page at the very top to register service worker if (navigator.serviceWorker.controller) { console.log('[PWA Builder] active service worker found, no need to register') } else { //Register the ServiceWorker navigator.serviceWorker.register('pwabuider-sw.js', { scope: './' }).then(function(reg) { console.log('Service worker has been registered for scope:'+ reg.scope); }); } Register the SW
  25. 25. @joshholmes /ˈfrikSH(ə)n/
  26. 26. @joshholmes Poor performance is friction
  27. 27. @joshholmes Source: eMarketer
  28. 28. @joshholmes Source: eMarketer Which of these matter to your context… Always measure what matters…
  29. 29. @joshholmes A 1s delay in page load can reduce conversions by 7% Source: Kissmetrics
  30. 30. @joshholmes For an online shop earning $100k/day, that’s about $2.5m in lost sales Source: Kissmetrics
  31. 31. @joshholmes For Amazon, 1s is worth about $1.6b in sales Source: HubSpot
  32. 32. @joshholmes Source: eMarketer
  33. 33. @joshholmes 53% abandon websites that take more than 3s to load Source: Google
  34. 34. @joshholmes By shaving 7s off load, Edmunds increased page views by 17% & ad revenue by 3% Source: HubSpot
  35. 35. @joshholmes Mozilla reduced page load by 2.2s and saw a 15.4% increase in downloads Source: HubSpot
  36. 36. @joshholmes Performance matters
  37. 37. @joshholmes /dôɡˈfo͞odiNG/
  38. 38. @joshholmes Let’s talk (briefly) about page load
  39. 39. @joshholmes time Your Device The Web DNS Lookup Icons by Mahmure Alp
  40. 40. @joshholmes time Your Device The Web TCP Handshake Icons by Mahmure Alp
  41. 41. @joshholmes time Your Device The Web Request Icons by Mahmure Alp
  42. 42. @joshholmes time Your Device The Web Server Processing Icons by Mahmure Alp
  43. 43. @joshholmes time Your Device The Web Response Icons by Mahmure Alp
  44. 44. @joshholmes Icons by Mahmure Alp
  45. 45. @joshholmes WEB RUNTIME ARCHITECTURE
  46. 46. @joshholmes WEB RUNTIME ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  47. 47. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  48. 48. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  49. 49. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  50. 50. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  51. 51. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  52. 52. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  53. 53. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  54. 54. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  55. 55. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  56. 56. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  57. 57. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  58. 58. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  59. 59. @joshholmes WEB PLATFORM ARCHITECTURE Networking / Cache Parsers 1 2 7 43 8 9 5 6 DOM Tree Formatting Layout Painting 1 2 7 43 8 9 5 6 Display Tree Compositing DOM API & Capabilities JavaScript DMANIP Hit Testing InputCSS Cascade
  60. 60. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  61. 61. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  62. 62. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  63. 63. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  64. 64. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  65. 65. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  66. 66. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  67. 67. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  68. 68. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  69. 69. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  70. 70. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  71. 71. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  72. 72. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  73. 73. @joshholmes DOM Parsing <html> <head> <title>Silly example</title> <script src="head.js"></script> <link rel="stylesheet" href="main.css"> <style>h2 { font-weight: bold; }</style> <script>console.log('hi');</script> </head> <body> <img src="my.png" alt=""> <script src="body.js"></script> </body> </html>
  74. 74. @joshholmes Steps for better performance 1. Use native features whenever possible 2. Only include assets you actually need 3. Optimize everything 4. Think about when you load assets 5. Consider how you load assets 6. Only load assets when they add value 75
  75. 75. @joshholmes Step 1: Use native features whenever possible
  76. 76. @joshholmes (they’re effectively free)
  77. 77. @joshholmes Por exemplo <header> Header content… </header>
  78. 78. @joshholmes Por exemplo <input id="n" name="n" required aria-required="true" autocorrect="off" autocapitalize="words" placeholder="Sir Tim Berners Lee" autocomplete="name" >
  79. 79. @joshholmes Por exemplo <input type="email" id="e" name="e" required aria-required="true" autocorrect="off" autocapitalize="off" autocomplete="email" placeholder="you@yourdomain.tld" >
  80. 80. @joshholmes Por exemplo @media (min-width:600px) { .gridded { display: grid; grid-template-columns: 1fr 300px; grid-gap: 20px; } }
  81. 81. @joshholmes Step 2: Only include assets you actually need
  82. 82. @joshholmes Great tools, possibly overkill
  83. 83. @joshholmes Every tool has a cost Framework Size (Compressed) Bootstrap 2 149 kB Bootstrap 3 103 kB Angular 1.4 51 kB Ember 2.2.0 111 kB Foundation 4 266 kB jQuery 32 kB UI Kit 86 kB React 16 + React DOM 35 kB Vue 2.4.2 20 kB
  84. 84. @joshholmes Chances are, your library of choice is on a CDN
  85. 85. @joshholmes time Your Device The Web Icons by Mahmure Alp
  86. 86. @joshholmes time Your Device The Web Icons by Mahmure Alp You can optimize this
  87. 87. @joshholmes Find the server early <link rel="prefetch" href="https://cdn.foo.com">
  88. 88. @joshholmes time Your Device The Web Icons by Mahmure Alp You can optimize this
  89. 89. @joshholmes Go for the handshake <link rel="preconnect" href="https://cdn.foo.com">
  90. 90. @joshholmes time Your Device The Web Icons by Mahmure Alp You can even optimize this
  91. 91. @joshholmes Grab that resource <link rel="preload" href="https://cdn.foo.com/jquery.min.js" as="script">
  92. 92. @joshholmes Download isn’t everything Source: The Filament Group
  93. 93. @joshholmes Download isn’t everything Framework Method/function operations/s Vanilla JS document.getElementById() 12,137,211 Dojo dojo.byId(); 5,443,343 Prototype $() 2,940,734 Ext JS Ext.get() 997,562 jQuery $() 350,557 YUI YAHOO.util.Dom.get() 326,534 MooTools document.id() 78,802 Source: VanillaJS
  94. 94. @joshholmes
  95. 95. @joshholmes We used some hints though <link rel="preconnect" href="//10kapart.blob.core.windows.net"> <link rel="preconnect" href="//cdnjs.cloudflare.com"> <link rel="preconnect" href="//www.google-analytics.com">
  96. 96. @joshholmes Step 3: Optimize everything
  97. 97. @joshholmes Our approach to CSS (Gulp) 1. Write modular CSS in Sass (+ Breakup for MQ management) 2. Compile CSS with a precision of 4 decimal places (gulp-sass) 3. Fallbacks for the last 2 browser versions (gulp-autoprefixer) 4. CSS shorthand declarations if possible (gulp-shorthand) 5. Remove any unused declarations/rule sets (gulp-uncss) 6. Optimize the files (gulp-csso) 7. Minify (gulp-clean-css) 8. Gzip (gulp-zopfli) 9. Brotli (gulp-brotli) 103
  98. 98. @joshholmes Before
  99. 99. @joshholmes After
  100. 100. @joshholmes Our approach to JS (Gulp) 1. Write modular JavaScript, grouped as appropriate 2. Combine files based on folder structure (gulp-folders, gulp-concat) 3. Create an wrapping closure to isolate from other JS (gulp-insert) 4. Minify (gulp-uglify) 5. Gzip (gulp-zopfli) 6. Brotli (gulp-brotli) 106
  101. 101. @joshholmes Results about 8 kB all-up
  102. 102. @joshholmes Interesting side note
  103. 103. @joshholmes We also minified & pre-compressed our HTML
  104. 104. @joshholmes Step 4: Think about when you load assets
  105. 105. @joshholmes We had 10 JS files ๏ Global ‣ main.js - the site’s library ‣ serviceworker.js - The site’s service worker ๏ Browser-specific ‣ html5shiv.js - local copy of the HTML5 Shiv for < IE9 111
  106. 106. @joshholmes We had 10 JS files ๏ Page-specific ‣ enter.js - Entry form-related code ‣ form-saver.js - Used to save form entries locally until submitted ‣ hero.js - Runs the SVG animation on the homepage ‣ home.js - Handles homepage-specific tasks ‣ project.js - Used on project pages during voting ‣ update.js - Handles the winner update form 112
  107. 107. @joshholmes Per the common wisdom <script src="/j/main.min.js"></script> </body> </html>
  108. 108. @joshholmes No need to run immediately <script src="/j/main.min.js"></script> <script src="/j/home.min.js" defer ></script> </body> </html>
  109. 109. @joshholmes Run whenever you can <script src="/j/main.min.js"></script> <script src="/j/home.min.js" async ></script> </body> </html>
  110. 110. @joshholmes Consider dependencies <script src="/j/main.min.js"></script> <script src="/j/home.min.js" async></script>
  111. 111. @joshholmes Consider dependencies <script src="/j/main.min.js" async></script> <script src="/j/home.min.js" async></script>
  112. 112. @joshholmes “race condition”
  113. 113. @joshholmes Avoid race conditions <script src="/j/main.min.js"></script> <script src="/j/home.min.js" async></script>
  114. 114. @joshholmes Why so many separate files?
  115. 115. @joshholmes Connections in HTTP/1.1 Browser Per host Overall IE 9 6 35 IE 10 8 17 IE 11 13 17 Firefox 4+ 6 17 Opera 11+ 6 user defined Chrome 4+ 6 10 Safari 7+ 6 17
  116. 116. @joshholmes time Your Device The Web HTTP/1.1 Icons by Mahmure Alp
  117. 117. @joshholmes HTTP/2 creates a single connection and contents stream in
  118. 118. @joshholmes time Your Device The Web HTTP/2 Icons by Mahmure Alp
  119. 119. @joshholmes Source: A List Apart
  120. 120. @joshholmes Demo: Akamai
  121. 121. @joshholmes Source: A List Apart
  122. 122. @joshholmes Step 5: Consider how you load assets
  123. 123. @joshholmes Start simple <link rel="stylesheet" href="/c/d.min.css"> <link rel="stylesheet" href="/c/a.min.css" media="only screen">
  124. 124. @joshholmes Fault tolerance FTW! <link rel="stylesheet" href="/c/d.min.css"> <link rel="stylesheet" href="/c/a.min.css" media="only screen">
  125. 125. @joshholmes Conditional scripting <!--[if lt IE 9]> <script src="/j/html5shiv.min.js"></script> <![endif]-->
  126. 126. @joshholmes Conditional scripting <!--[if gt IE 8]><!--> <script src="/j/main.min.js"></script> <script src="/j/home.min.js" async ></script> <!--<![endif]--> </body> </html>
  127. 127. @joshholmes Conditional imagery
  128. 128. @joshholmes Conditional images @media (min-width: 36.375em) { .presented-by [href*=microsoft]::before { background-image: url(/i/c/edge.png); background-image: url(/i/c/edge.svg), none; … } }
  129. 129. @joshholmes Conditional images @media (min-width: 36.375em) { .presented-by [href*=microsoft]::before { background-image: url(/i/c/edge.png); background-image: url(/i/c/edge.svg), none; … } }
  130. 130. @joshholmes Conditional images @media (min-width: 36.375em) { .presented-by [href*=microsoft]::before { background-image: url(/i/c/edge.png); background-image: url(/i/c/edge.svg), none; … } }
  131. 131. @joshholmes Conditional images @media (min-width: 36.375em) { .presented-by [href*=microsoft]::before { background-image: url(/i/c/edge.png); background-image: url(/i/c/edge.svg), none; … } }
  132. 132. @joshholmes Conditional animation
  133. 133. @joshholmes How do we get there? JS? No No imageLoad Yes <> SVG support? Yes SVG Ajax request SVG Yank out script & add to document No picture Save the markup for next page load NoYes Verify browser width condition
  134. 134. @joshholmes Step 6: Only load assets when they add value
  135. 135. @joshholmes
  136. 136. @joshholmes
  137. 137. @joshholmes Evaluate images case-by-case ๏ Does the image reiterate information found in the surrounding text? ๏ Is the image necessary to understand the surrounding content? ๏ Does the image contain text? ๏ Is the image a graph, chart, or table? ๏ Could the content of the image be presented in a different format that would not require an image? ๏ Is the image purely presentational? 143
  138. 138. @joshholmes 53% of the average web page Source: Internet Archive
  139. 139. @joshholmes And they don’t always fit
  140. 140. @joshholmes Source: The Outline
  141. 141. @joshholmes If you can avoid using an image, do it
  142. 142. @joshholmes If you need an image, choose the best format
  143. 143. @joshholmes Quick format recap ๏ GIF ‣ for images with large swaths of solid colors ‣ Binary transparency ๏ JPG ‣ For photographs and images with gradations of color ‣ Can be compressed (introduces artifacts) 149
  144. 144. @joshholmes Quick format recap ๏ PNG (8-Bit) ‣ Alternative to GIF ‣ Can support alpha transparency (with the right creation software) ๏ PNG (24-bit) ‣ Alternative to JPG ‣ Usually larger than JPGs ‣ Supports alpha tranparency 150
  145. 145. @joshholmes Quick format recap ๏ WebP ‣ Newer format, not universally supported ‣ Smaller than JPGs and 24-bit PNGs ‣ Support alpha transparency ‣ and so much more… 151
  146. 146. @joshholmes Sometimes images are “nice to have”
  147. 147. @joshholmes
  148. 148. @joshholmes
  149. 149. @joshholmes Oh wait… optimize everything
  150. 150. @joshholmes
  151. 151. @joshholmes
  152. 152. @joshholmes Source: 38 kB JPG
  153. 153. @joshholmes B&W: 35 kB JPG (-7%)
  154. 154. @joshholmes Crop & Resize: 12 kB JPG (-68%)
  155. 155. @joshholmes Blur & optimize: 9 kB JPG (-76%)
  156. 156. @joshholmes
  157. 157. @joshholmes WebP: 4 kB (-89%)JPG: 9 kB (-76%)
  158. 158. @joshholmes Steps for better performance 1. Use native features whenever possible 2. Only include assets you actually need 3. Optimize everything 4. Think about when you load assets 5. Consider how you load assets 6. Only load assets when they add value 179
  159. 159. @joshholmes https://webhint.io
  160. 160. @joshholmes Every choice we make affects our users’ experiences
  161. 161. @joshholmes Let’s spend our time to save it for our users
  162. 162. @joshholmes Speedy performance is a great user experience
  163. 163. @joshholmes Performant PWAs Josh Holmes josh.holmes@microsoft.com
  • ErikEspaaCAPM

    May. 5, 2019

Your users deserve a fast and responsive web app and PWAs help you step that up a notch through notifications, offline support and more. There’s a lot that goes into that from understanding how the DOM tree works and how that plays with CSS and JavaScript to how to leverage the ServiceWorker for cashing and push notifications. In this session, we’ll build a PWA that show cases many of the things you need to keep in mind when building a great and fast progressive web app.

Vues

Nombre de vues

121

Sur Slideshare

0

À partir des intégrations

0

Nombre d'intégrations

14

Actions

Téléchargements

6

Partages

0

Commentaires

0

Mentions J'aime

1

×