Frontend Web Performance - better, faster, stronger

22725c2d3eb331146549bf0d5d3c050c?s=47 stefan judis
October 10, 2017
1.3k

Frontend Web Performance - better, faster, stronger

22725c2d3eb331146549bf0d5d3c050c?s=128

stefan judis

October 10, 2017
Tweet

Transcript

  1. Frontend Web Performance better, faster, stronger @stefanjudis

  2. Stefan Judis Frontend Developer, Occasional Teacher, Meetup Organizer ❤ Open

    Source, Performance and Accessibility ❤ @stefanjudis
  3. None
  4. Start performance tooling today PERF TOOLING www.perf-tooling.today

  5. I live in a bubble! (Usually)

  6. None
  7. None
  8. None
  9. I live in a bubble!

  10. Recent MacBook Pro Recent phone with 5GB EU wide fast

    data plan
  11. Bruce Lawson previously @ Opera Where will your next customer

    come from?
  12. 12 731 MILLION CHINA TOP 10 COUNTRIES WITH THE HIGHEST

    NUMBER OF INTERNET USERS 462 MILLION INDIA 286 MILLION USA 139 MILLION BRAZIL 132 MILLION INDONESIA 118 MILLION JAPAN 104 MILLION RUSSIA 93 MILLION NIGERIA 71 MILLION GERMANY 69 MILLION MEXICO www.internetworldstats.com/top20.htm
  13. Finnland France Denmark Great Britian Ireland Italy Spain Germany USA

    Hungary 0GB 25GB 50GB 75GB 100GB de.statista.com/infografik/6188/4g-im-laendervergleich/ data with 4g for 35€ unlimited 50 40 20 10 8 7 4 2 1
  14. whatdoesmysitecost.com

  15. 1GB for 10€

  16. 1GB for 10€ 400 times 2.5MB

  17. 1GB for 10€ 400 times 2.5MB 1 VISIT costs 0.025€

  18. 1GB for 10€ 400 times 2.5MB 1 VISIT costs 0.025€

    1 MB costs 0.01€!!!
  19. httparchive.org/

  20. AVERAGE PAGE WEIGHT DESKTOP NOVEMBER 2010 702 KB SEPTEMBER 2017

    3376 KB
  21. AVERAGE PAGE WEIGHT MOBILE JUNE 2011 377 KB SEPTEMBER 2017

    2949 KB
  22. AVERAGE PAGE WEIGHT MOBILE JUNE 2011 377 KB SEPTEMBER 2017

    2949 KB 0.03 €
  23. But it's not only about page weight...

  24. It's about user experience

  25. More weight doesn't mean more wait Scott Jehl filament group

  26. None
  27. www.filamentgroup.com/lab/weight-wait.html 8 SECONDS FASTER PAINT WITHOUT REMOVING CONTENT

  28. None
  29. DISTRACT THE USER

  30. Web Performance matters!

  31. Pinterest increased 15% SEO traffic and 15% conversion rate to

    signup. BBC loses 10% of users for every additional second in load time. The Trainline reduced latency and customers spent an extra ~$11.5 million a year.
  32. Get your business use case! WPO stats wpostats.com

  33. But let's kick things off ctfl.io/fe-web-perf

  34. github.com/stefanjudis/webperf-101-workshop github.com/stefanjudis/webperf-101-workshop-final

  35. - getting started - git clone git@github.com:stefanjudis/webperf-101-workshop.git npm i npm

    run dev git clone git@github.com:stefanjudis/webperf-101-workshop-final.git npm i npm run dev
  36. None
  37. EXAMPLE SITE (BASED ON BOOTSTRAP) CHROME DESKTOP DSL CONNECTION

  38. EXAMPLE SITE (BASED ON BOOTSTRAP) IPHONE 6 3G CONNECTION

  39. - before vs after - www.webpagetest.org/video/compare.php?tests=171010_KV_c9dbe9afd5435e841acb6ee0f8b4342f, 171010_0S_90d4ae1819496d143a8342a76351ab23

  40. - before vs after - www.webpagetest.org/result/171010_1S_d994486799ea8416dcd982fd4139976d/ www.webpagetest.org/result/171010_1S_d994486799ea8416dcd982fd4139976d/

  41. Measure everything!

  42. WAYS TO MEASURE PERFORMANCE Synthetic Monitoring Real User Monitoring

  43. - Synthetic Monitoring - calibreapp.com/ speedcurve.com/

  44. - Synthetic Monitoring - www.sitespeed.io/

  45. developers.google.com/speed/pagespeed/insights/? url=https%3A%2F%2Fstefanjudis.github.io%2Fwebperf-101-workshop%2Fdist%2F

  46. - Synthetic Monitoring - www.webpagetest.org/result/171009_97_b14478acf4e583428d01a7b7bd202fbb/

  47. - Real User Monitoring - https://analytics.google.com mpulse.soasta.com/concerto/Central?anon=true

  48. www.perf-tooling.today/tools?q=metrics

  49. - Real User Monitoring -

  50. TOPICS 01 02 03 04 05 06 07 10 11

    12 13 14 15 SCRIPT LOADING LAZY LOADING IMAGE FORMATS IMAGE COMPRESSION VIDEO TEXT COMPRESSION RESPONSIVE IMAGES FONT LOADING CONCAT & MINIFY CRITICAL PATH NEW METRICS PRE LOADING HTTP/2 08 ICONS 16 BUDGETING 09 CACHING 17 UNUSED CODE
  51. 01 IMAGE FORMATS

  52. Images are 53% of the overall traffic httparchive.org/interesting.php?a=All&l=Sep%201%202017

  53. TRADITIONAL IMAGE FORMATS GIF JPG PNG SVG

  54. Is it a vector graphic? YES NO

  55. Is it a vector graphic? SVG YES GIF PNG JPEG

    NO
  56. Need animation? YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization

  57. Need animation? GIF YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization

  58. Need animation? GIF Need to preserve fine detail, with highest

    resolution or transparency? YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization
  59. Need animation? GIF Need to preserve fine detail, with highest

    resolution or transparency? Need a large color palette? (+256 colors) YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization
  60. Need animation? GIF Need to preserve fine detail, with highest

    resolution or transparency? Need a large color palette? (+256 colors) PNG-8 PNG-24 YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization
  61. Need animation? GIF Need to preserve fine detail, with highest

    resolution or transparency? Need a large color palette? (+256 colors) PNG-8 PNG-24 JPEG YES NO YES NO YES NO developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/image-optimization
  62. 2000×1038

  63. gif – 1.4MB (0.01€)

  64. png-8 – 933KB (0.009€)

  65. png-24 – 3.2MB (0.03€)

  66. jpeg (Q65) – 399KB (0.004€)

  67. image formats “Are there alternatives?

  68. EXOTIC IMAGE FORMATS WEBP JPEG 2000 FLIF JPEG XR BPG

  69. EXOTIC IMAGE FORMATS WEBP JPEG 2000 FLIF JPEG XR No

    support No support BPG
  70. webp – 121KB (0.001€)

  71. progressive enhancement <picture> <source srcset="https://.../some-image.jxr2" type="image/vnd.ms-photo"> <source srcset="https://.../some-image.jp2" type="image/jp2"> <source

    srcset="https://.../some-image.webp" type="image/webp"> <img src="https://.../some-image.png" alt="Some image"> </picture> www.useragentman.com/blog/2015/01/14/using-webp-jpeg2000-jpegxr-apng-now-with-picturefill-and-modernizr/
  72. server side detection <IfModule mod_rewrite.c> RewriteEngine On # Check if

    browser support WebP images RewriteCond %{HTTP_ACCEPT} image/webp # Check if WebP replacement image exists RewriteCond %{DOCUMENT_ROOT}/$1.webp -f # Serve WebP image instead RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] </IfModule> <IfModule mod_headers.c> Header append Vary Accept env=REDIRECT_accept </IfModule> AddType image/webp .webp images.guide/#-a-id-how-do-i-serve-webp-href-how-do-i-serve-webp-how-do-i-serve-webp-a- .htaccess
  73. server side detection .htaccess www.igvita.com/posts/12/xbandwidth-vs-latency.png.pagespeed.ic.rKtq8Mdb7q.jpg

  74. feature detection github.com/Modernizr/Modernizr/blob/ 5eea7e2a213edc9e83a47b6414d0250468d83471/feature-detects/img/webp.js

  75. CODING TIME

  76. 02 IMAGE COMPRESSION

  77. - jpeg quality -

  78. - jpeg compression modes -

  79. calendar.perfplanet.com/2016/even-faster-images-using-http2-and-progressive-jpegs/

  80. JPEG ENCODER LIBJPEG MOZJPEG GUETZLI

  81. libjpeg – 399KB (0.004€)

  82. guetzli – 336KB (0.003€)

  83. mozjpeg – 197KB (0.002€)

  84. github.com/imagemin/imagemin-guetzli github.com/imagemin/imagemin-mozjpeg github.com/imagemin/imagemin

  85. github.com/JamieMason/ImageOptim-CLI imageoptim.com/mac

  86. None
  87. CODING TIME

  88. The joy of optimizing by Una Kravets vimeo.com/190871719

  89. images.guide/

  90. 03 RESPONSIVE IMAGES

  91. load images responsively How I learned to love JavaScript Or

    how I saved some bytes... How I learned to love JavaScript Desktop 21MB (0.21€) Mobile 30MB (0.30€)
  92. None
  93. load images responsively <img src="https://.../some-hero-image.jpg" srcset="https://.../some-hero-image-560.jpg 560w, https://.../some-hero-image-800.jpg 800w, https://.../some-hero-image-1920.jpg

    1920w" sizes="100vw" alt="Seattle Skyline">

  94. load images responsively <img src="https://.../some-hero-image.jpg" srcset="https://.../some-hero-image.jpg?w=560 560w, https://.../some-hero-image.jpg?w=800 800w, https://.../some-hero-image.jpg?w=1920

    1920w" sizes="100vw" alt="Seattle Skyline">

  95. all jpeg ~170KB (0.002€)

  96. CODING TIME

  97. 04 VIDEO

  98. Average video response size is 789KB httparchive.org/interesting.php?a=All&l=Sep%2015%202017

  99. None
  100. # $ compress_video caniuse.mp4 caniuse_compressed.mp4 function compress_video() { if !

    [ $# -eq 2 ]; then echo "Wrong parameter usage: \n $ compress_video <inputFile> <outputFile>" return 1 fi ffmpeg -i $1 -vcodec h264 -b:v 1000k -acodec mp2 $2 } compress video on the fly
  101. mp4 vs. webm

  102. <video autoplay muted loop playsinline preload="metadata"> <source src="https://.../some-video.webm" type="video/webm"> <source

    src="https://.../some-video.mp4" type="video/mp4"> </video> progressive enhancement
  103. 5.2M share-inbox.mp4 (0.05€) 1.1M share-inbox_web.mp4 (0.01€) 515K share-inbox_web.webm (0.005€) compression

  104. # $ prepare_video caniuse.mp4 caniuse_compressed function prepare_video() { if !

    [ $# -eq 1 ]; then echo "Wrong parameter usage: \n $ compress_video <inputFile> <outputFileBase>" return 1 fi ffmpeg -i $1 -vcodec h264 -b:v 1000k -acodec mp2 $2.mp4 ffmpeg -i $2.mp4 -strict -2 $2.webm } compress video on the fly github.com/stefanjudis/.dotfiles/blob/master/functions.zsh#L61-L69
  105. Use video responsibly

  106. www.webpagetest.org/video/view.php?id=150209_e46843cf0dc768ccc6641e944d3551d05175dd9f use video responsibly

  107. 05 TEXT COMPRESSION

  108. twitter.com/dougsillars/status/917464153522102272

  109. gzip <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType

    DEFLATE image/svg+xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/xml ... ... ... </IfModule> .htaccess
  110. 2.4M application-97681b5991.min.js (0.02€) 708K application-97681b5991.min.js.gz (0.007€) gzip .htaccess

  111. accept-encoding: gzip, deflate, br

  112. brotli 2.4M application-97681b5991.min.js (0.02€) 708K application-97681b5991.min.js.gz (0.007€) 526K application-97681b5991.min.js.br (0.005€)

    samsaffron.com/archive/2016/06/15/the-current-state-of-brotli-compression brotli css-tricks.com/brotli-static-compression/
  113. brotli caniuse.com/#feat=brotli

  114. 06 CACHING

  115. jakearchibald.com/2016/caching-best-practices/

  116. cache-control: max-age=31556926 caching of static assets www.stefanjudis.com/_nuxt/pages/index.3b10328682a1efde514e.js https://images.contentful.com/f20lfrunubsq/qZrrGql6VwaoE2YU8CUuE/ a4276082432402bd90933ab3de335bf7/stock-photo-227882431.jpg?w=300 cache-control:

    max-age=590039 ~1 YEAR ~1 WEEK
  117. cache-control: max-age=31556926 caching of static assets www.stefanjudis.com/_nuxt/pages/index.3b10328682a1efde514e.js https://images.contentful.com/f20lfrunubsq/qZrrGql6VwaoE2YU8CUuE/ a4276082432402bd90933ab3de335bf7/stock-photo-227882431.jpg?w=300 cache-control:

    max-age=590039 ~1 YEAR ~1 WEEK
  118. caching of static assets https://www.facebook.com/rsrc.php/v3/yD/r/FLAXZ9xHT18.js ~1 YEAR cache-control: max-age=31536000,immutable

  119. caching of static assets

  120. caching of static assets

  121. caching of static assets “When you reload, browsers revalidate the

    page that you are currently on, even if that page hasn't expired yet. However, they also go a step further and revalidate all sub-resources on the page — things like images and JavaScript files.
  122. code.facebook.com/posts/557147474482256/this-browser-tweak-saved-60-of-requests-to-facebook/

  123. hacks.mozilla.org/2017/01/using-immutable-caching-to-speed-up-the-web/

  124. - immutable - developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Browser_compatibility cache-control: public,max-age=31536000,immutable

  125. 07 CONCAT & MINIFY

  126. github.com/mishoo/UglifyJS

  127. github.com/jakubpawlowicz/clean-css

  128. github.com/kangax/html-minifier

  129. CODING TIME

  130. 08 ICONS

  131. ICON FONTS

  132. cloudfour.com/thinks/seriously-dont-use-icon-fonts/

  133. Using SVGs <img src="image.svg" alt="image"> load as img <svg version="1.1"

    id="Layer_1" xmlns="http://www.w3.org/2000/svg" class="shopping-cart" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="5 24.366 90 61.125" xml:space="preserve"> <g>...</g> </svg> inline SVG .element { background-image: url(/images/image.svg); } load SVG in CSS
  134. Using SVGs <svg style="display: none;"> <defs> <symbol id="basketball" viewBox="0 0

    100 100"> <title>Basketball</title> <path d="M28.1,3 ... "/> </symbol> </defs> </svg> <svg class="icon-basketball"> <use xlink:href="#basketball"></use> </svg> load as an icon system
  135. www.perf-tooling.today/tools

  136. https://github.com/svg/svgo jakearchibald.github.io/svgomg/

  137. CODING TIME

  138. 09 SCRIPT LOADING

  139. script loading “Put scripts at the end of the file,

    right?
  140. script loading <script src="./some-javascript.js"></script> <script src="./some-javascript.js" async></script> <script src="./some-javascript.js" defer></script>

    vs vs
  141. script loading <script src="./some-javascript.js"></script> HTML parsing

  142. script loading <script src="./some-javascript.js"></script> HTML parsing HTML parsing paused HTML

    parsing Script fetch Script execution
  143. script loading <script src="./some-javascript.js" async></script> HTML parsing async

  144. script loading <script src="./some-javascript.js" async></script> HTML parsing HTML parsing Script

    fetch Script execution async
  145. script loading <script src="./some-javascript.js" defer></script> HTML parsing defer

  146. script loading <script src="./some-javascript.js" defer></script> HTML parsing Script fetch Script

    execution defer
  147. script loading HTML parsing fetch async vs. defer async defer

    fetch HTML parsing fetch fetch 1 2
  148. script loading HTML parsing fetch async vs. defer async defer

    fetch execution execution HTML parsing fetch fetch execution execution 1 2
  149. bitsofco.de/async-vs-defer/

  150. script loading “Which one do you prefer?

  151. calendar.perfplanet.com/2016/prefer-defer-over-async/

  152. SPOF

  153. Without blocking script With blackboxed script

  154. None
  155. None
  156. <script type=“text/javascript" src="https://seal.websecurity.norton.com/getseal? host_name=www.thehiddencost.de&amp;lang=de"></script>

  157. <script type=“text/javascript" src=“https://seal.websecurity.norton.com/getseal? host_name=www.thehiddencost.de&amp;lang=de" async></script>

  158. chrome.google.com/webstore/detail/spof-o-matic/plikhggfbplemddobondkeogomgoodeg

  159. TRUST

  160. “What's the ROI of your 3rd parties? 3rd parties

  161. requestmap.webperf.tools/render/171008_D7_e0fbc654e0da0b7b97b1c0f53964f7d2

  162. REMOVE, REMOVE, ...

  163. 3rd parties

  164. www.webpagetest.org/result/171009_CV_a6df9efc6f6861175a3963b22d1f1103/1/details/#waterfall_view_step1

  165. twitter.com/DasSurma/status/915573188398022656

  166. CODING TIME

  167. 10 CRITICAL PATH

  168. critical path “ Get something on the screen as soon

    as possible
  169. http connection “What's needed to establish an HTTP connection?

  170. http connection DNS lookup initial connection TCP SSL/TLS negotiation TTFB

    content download
  171. hpbn.co/building-blocks-of-tcp/ Roundtrip time 56ms

  172. latency on mobile (3g connection) de.slideshare.net/metrofun/reduce-mobile-latency Control plane latency Internet

    routing latency Internal latency (CDNs, ISPs, Caches, Proxies) (Firewalls, Load Balancers, Servers) ~600ms ~200ms
  173. www.igvita.com/2012/07/19/latency-the-new-web-performance-bottleneck/ latency matters

  174. latency matters

  175. inline critical CSS index.html main.css

  176. inline critical CSS index.html start render main.css

  177. inline critical CSS index.html (inline CSS) main.css

  178. inline critical CSS start render index.html (inline CSS) main.css

  179. github.com/filamentgroup/loadCSS

  180. inline critical CSS <head> <style> // critical styles </style> <link

    rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="path/to/mystylesheet.css"></noscript> <script> /*! loadCSS. [c]2017 Filament Group, Inc. MIT License */ (function(){ ... }()); /*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */ (function(){ ... }()); </script> </head>
  181. github.com/addyosmani/critical

  182. speakerdeck.com/patrickhamann/css-and-the-first-meaningful-paint-css-conf-eu-may-2017

  183. 11 UNUSED CODE

  184. None
  185. github.com/giakki/uncss

  186. ANALYSE PACKAGES

  187. None
  188. github.com/twbs/bootstrap/blob/v4-dev/scss/bootstrap.scss

  189. CODING TIME

  190. 12 LAZY LOADING

  191. lazy loading “How do you
 implement lazy loading?

  192. function isElementInViewport (el) { var rect = el.getBoundingClientRect(); return (

    rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } How to tell if a DOM element is visible in the current viewport? stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
  193. function isElementInViewport (el) { var rect = el.getBoundingClientRect(); // can

    trigger force layout/reflow return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } How to tell if a DOM element is visible in the current viewport? stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
  194. WHAT FORCES LAYOUT / REFLOW gist.github.com/paulirish/5d52fb081b3570c81e3a

  195. Implementation with 'scroll' const speakers = [...document.querySelectorAll('.lazy')]; window.addEventListener('scroll', () =>

    { speakers.forEach(elem => { if (isElementInViewport(elem)) { // load image } }); });
  196. Implementation with 'scroll' const speakers = [...document.querySelectorAll('.lazy')]; window.addEventListener('scroll', () =>

    { // really expensive speakers.forEach(elem => { if (isElementInViewport(elem)) { // load image } }); });
  197. Implementation with 'scroll' 60FPS 1s / 60 16ms

  198. Implementation with 'scroll' 60FPS 1s / 60 10ms 16ms

  199. None
  200. None
  201. None
  202. None
  203. Intersection Observer

  204. - Intersection Observer - (function() { const options = {

    threshold: 1.0 }; const intersectionObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { // load image } }); }, options); [...document.querySelectorAll('.lazy')] .forEach(elem => intersectionObserver.observe(elem)); })();
  205. - Intersection Observer - (function() { const options = {

    threshold: 1.0 }; const intersectionObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { // load image } }); }, options); [...document.querySelectorAll('.lazy')] .forEach(elem => intersectionObserver.observe(elem)); })();
  206. - Intersection Observer - (function() { const options = {

    threshold: 1.0 }; const intersectionObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { // load image } }); }, options); [...document.querySelectorAll('.lazy')] .forEach(elem => intersectionObserver.observe(elem)); })();
  207. (function() { const options = { threshold: 1.0 }; const

    intersectionObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { // load image } }); }, options); [...document.querySelectorAll('.lazy')] .forEach(elem => intersectionObserver.observe(elem)); })(); - Intersection Observer -
  208. - Intersection Observer - caniuse.com/#feat=intersectionobserver * in development *

  209. github.com/w3c/IntersectionObserver/tree/master/polyfill

  210. github.com/ApoorvSaxena/lozad.js

  211. CODING TIME

  212. 13 PRE LOADING

  213. rel="preconnect" rel="dns-prefetch" rel="preload" rel="prefetch" www.w3.org/TR/resource-hints/#dns-prefetch-link-relation-type www.w3.org/TR/resource-hints/#preconnect-link-relation-type www.w3.org/TR/resource-hints/#prefetch-link-relation-type www.w3.org/TR/preload/

  214. Preload resources you have high- confidence will be used in

    the current page. Prefetch resources likely to be used for future navigations across multiple navigation boundaries. “
  215. www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/

  216. medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf

  217. www.stefanjudis.com

  218. - rel="dns-prefetch" - caniuse.com/#feat=link-rel-dns-prefetch

  219. - rel="preconnect" - caniuse.com/#feat=link-rel-preconnect

  220. - rel="preload" - caniuse.com/#feat=link-rel-preload

  221. - rel="prefetch" - caniuse.com/#feat=link-rel-prefetch

  222. Link: <https://widget.com>; rel=dns-prefetch Link: <https://example.com>; rel=preconnect Link: <https://example.com/next-page.html>; rel=prefetch; Link:

    <https://example.com/logo-hires.jpg>; rel=preload; as=image; Usage <link rel="dns-prefetch" href="//widget.com"> <link rel="preconnect" href="//cdn.example.com"> <link rel="prefetch" href="//example.com/next-page.html"> <link rel="preload" href="//example.com/logo-hires.jpg" as="image"> link element header
  223. medium.com/@benschwarz/the-critical-request-90bb47da5769

  224. CODING TIME

  225. 15 FONT LOADING

  226. - font loading behavior - FOUT? FOIT?

  227. - font loading behavior - FOUT FOIT www.bramstein.com/writing/web-font-loading-patterns.html

  228. - font loading behavior -

  229. FOIT! - font loading behavior -

  230. - font loading behavior - FOUT FOIT FOIT FOIT FOIT

    3s 3s 3s 3s - www.zachleat.com/web/fout-foit-history/
  231. body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,

    sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; } github.com
  232. css-tricks.com/snippets/css/system-font-stack/

  233. FONTS ON MOBILE?

  234. @media screen and (min-width: 52em) { body { font-family: 'Droid

    Sans', sans-serif; } } no fonts for mobile?
  235. - font rendering controls - font-display: auto; font-display: block; font-display:

    swap; font-display: fallback; font-display: optional; developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display
  236. - font rendering controls - font-display: auto; font-display: block; font-display:

    swap; font-display: fallback; font-display: optional; developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display
  237. - font rendering controls - caniuse.com/#feat=css-font-rendering-controls * * behind a

    flag
  238. - preload fonts - <link rel="preload" href="//example.com/font.woff2" as="font"> Link: <https://example.com/font.woff2>;

    rel=preload; as=font;
  239. www.zachleat.com/web/comprehensive-webfonts/

  240. 16 NEW METRICS

  241. new metrics “ What metrics do we have today?

  242. REAL USER METRICS (RUM) NAVIGATION TIMING API RESOURCE TIMING API

    USER TIMING API
  243. - Navigation Timing API - w3c.github.io/navigation-timing/ window.performance.timing

  244. - Navigation Timing API - { "navigationStart": 1494722965671, "unloadEventStart": 0,

    "unloadEventEnd": 0, "redirectStart": 0, "redirectEnd": 0, "fetchStart": 1494722965838, "domainLookupStart": 1494722965841, "domainLookupEnd": 1494722972627, "connectStart": 1494722972627, "connectEnd": 1494722973191, "secureConnectionStart": 1494722972815, "requestStart": 1494722973191, "responseStart": 1494722973667, "responseEnd": 1494722973681, "domLoading": 1494722973681, "domInteractive": 1494722974288, "domContentLoadedEventStart": 1494722974288, "domContentLoadedEventEnd": 1494722974320, "domComplete": 1494722974571, "loadEventStart": 1494722974571, "loadEventEnd": 1494722974574 } w3c.github.io/navigation-timing/ window.performance.timing
  245. - Navigation Timing API - w3c.github.io/navigation-timing/

  246. - Resource Timing API - window.performance.getEntriesByType('resource')

  247. - Resource Timing API - [ ..., { connectEnd: 117.69500000000001,

    connectStart: 117.69500000000001, decodedBodySize: 20133, domainLookupEnd: 117.69500000000001, domainLookupStart: 117.69500000000001, duration: 846.3100000000001, encodedBodySize: 20133, entryType: 'resource', fetchStart: 117.69500000000001, initiatorType: 'img', name: 'http://127.0.0.1:8080/image.png', redirectEnd: 0, redirectStart: 0, requestStart: 962.6750000000001, responseEnd: 964.0050000000001, responseStart: 963.45, secureConnectionStart: 0, startTime: 117.69500000000001, transferSize: 20391, workerStart: 0 } ] www.w3.org/TR/resource-timing-1/ window.performance.getEntriesByType('resource')
  248. [...Array(20)].forEach(cornify_add); - User Timing API - w3c.github.io/user-timing/ if (talksSeen ===

    nrOfTalks) { }
  249. - User Timing API - w3c.github.io/user-timing/ if (talksSeen === nrOfTalks)

    { // measure how long this takes performance.mark('cornify_start'); [...Array(20)].forEach(cornify_add); performance.mark('cornify_end'); performance.measure( 'cornify_processing_time', 'cornify_start', 'cornify_end' ); }
  250. - User Timing API - w3c.github.io/user-timing/ window.performance.getEntriesByType('mark') [ { duration:

    0 entryType: 'mark' name: 'cornify_start' startTime: 39613.885 }, ... ]
  251. - User Timing API - w3c.github.io/user-timing/ window.performance.getEntriesByType('measure') [ { duration:

    5.9900000000016 entryType: 'measure' name: 'cornify_processing_time' startTime: 46002.34500000001 }, ... ]
  252. ENTRY TYPE VALUES mark measure navigation resource ACCESSIBLE VIA getEntries

    getEntriesByType getEntriesByName
  253. GOOD METRICS

  254. - Speed Index -

  255. - Speed Index -

  256. <img src="hero.jpg" onload="performance.clearMarks('img displayed'); performance.mark('img displayed');"> <script> performance.clearMarks("img displayed"); performance.mark("img

    displayed"); </script> speedcurve.com/blog/user-timing-and-custom-metrics/ - custom metrics -
  257. - paint timing - www.w3.org/TR/paint-timing/ const perfObserver = new PerformanceObserver(list

    => { list.getEntries().forEach((entry) => { // Process entries // report back for analytics and monitoring // entry.name -> 'first-paint' // entry.name -> 'first-contentful-paint' } ); }); perfObserver.observe({entryTypes: ['paint']}); window.performance.getEntriesByType('paint')
  258. github.com/w3c/longtasks var perfObserver = new PerformanceObserver(function(list) { list.getEntries().forEach((entry) => {

    // Process entries // report back for analytics and monitoring // ... }); }); perfObserver.observe({entryTypes: ['longtask']}); - longtask - window.performance.getEntriesByType('longtask')
  259. - Performance Observer - developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver * * behind a flag

  260. None
  261. LEVERAGING THE METRICS THAT MOST AFFECT USER EXPERIENCE https://www.youtube.com/watch?v=6Ljq-Jn-EgU

  262. www.sitepen.com/blog/2017/10/06/improving-performance-with-the-paint-timing-api/

  263. 17 HTTP/2

  264. www.httpvshttps.com/

  265. www.httpvshttps.com/

  266. www.webpagetest.org/result/171008_AF_e0b47ffc2e10a439dc8fb25aecf6d8b4/

  267. www.webpagetest.org/result/171008_JA_c36bf495a6399f112b3c5eadb095190c/

  268. - Header Compression - blog.cloudflare.com/hpack-the-silent-killer-feature-of-http-2/

  269. PUSH?

  270. blogs.akamai.com/2017/03/http2-server-push-the-what-how-and-why.html

  271. jakearchibald.com/2017/h2-push-tougher-than-i-thought/

  272. The perfect preload will always be slightly slower than the

    perfect HTTP/2 push, since it doesn't need to wait for the browser to make the request. However, preloading is drastically simpler and easier to debug. I recommend using it today, as browser support is only going to get better – but do keep an eye on devtools to ensure your pushed items are being used. “
  273. tools.ietf.org/html/draft-ietf-httpbis-cache-digest-00

  274. HTTP/1.x vs HTTP/2 “Should you turn it on today?

  275. HTTP/1.x vs HTTP/2 “Hell yeah!

  276. HTTP/1.x vs HTTP/2 HTTP/1.x HTTP/2 DOMAIN SHARDING CONCAT FILES INLINE

    RESOURCES ? ? ?
  277. HTTP/1.x vs HTTP/2 HTTP/1.x HTTP/2 DOMAIN SHARDING CONCAT FILES INLINE

    RESOURCES DOMAIN SHARDING CONCAT FILES INLINE RESOURCES * * * always measure
  278. engineering.khanacademy.org/posts/js-packaging-http2.htm

  279. ALWAYS MEASURE!

  280. hpbn.co/

  281. 18 BUDGETING

  282. timkadlec.com/2013/01/setting-a-performance-budget/

  283. BIZ HAS TO BE ON BOARD

  284. www.webpagetest.org/video/compare.php? tests=171009_2S_68d930ae2b145ca338a70b97c93fbf19,171009_28_74873eb32a55 a5eb963d65c0d2253951

  285. github.com/addyosmani/psi developers.google.com/speed/pagespeed/insights/

  286. github.com/marcelduran/webpagetest-api www.webpagetest.org/

  287. github.com/GoogleChrome/lighthouse developers.google.com/web/tools/lighthouse/

  288. - performance budget - “ What is a good budget?

  289. - performance budget - 600 KB total page weight 01

    20 requests 02 03 1000 Speed Index 04 1s start render time 05 Start render 3-4s on 3g ...
  290. - performance budget - “You decide!

  291. What happens if something does not fit within the budget?

    Steve Souders Speedcurve Optimize? Remove? Don't do it?
  292. www.perf-tooling.today/tools?q=budget

  293. STILL TIME?

  294. You'll find everything here! PERF TOOLING www.perf-tooling.today

  295. Web Performance is the art of doing less
 but then

    in a smarter way.
  296. Thanks! @stefanjudis Slides https://ctfl.io/fe-web-perf