$30 off During Our Annual Pro Sale. View Details »

Frontend Web Performance - better, faster, stronger

stefan judis
October 10, 2017
1.6k

Frontend Web Performance - better, faster, stronger

stefan judis

October 10, 2017
Tweet

Transcript

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

    View Slide

  2. Stefan Judis
    Frontend Developer, Occasional Teacher, Meetup Organizer
    ❤ Open Source, Performance and Accessibility ❤
    @stefanjudis

    View Slide

  3. View Slide

  4. Start performance
    tooling today
    PERF TOOLING
    www.perf-tooling.today

    View Slide

  5. I live in a bubble!
    (Usually)

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. I live in a bubble!

    View Slide

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

    View Slide

  11. Bruce Lawson
    previously @ Opera
    Where will your next
    customer come from?

    View Slide

  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

    View Slide

  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

    View Slide

  14. whatdoesmysitecost.com

    View Slide

  15. 1GB for 10€

    View Slide

  16. 1GB for 10€
    400 times 2.5MB

    View Slide

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

    View Slide

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

    View Slide

  19. httparchive.org/

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  23. But it's not only about
    page weight...

    View Slide

  24. It's about
    user experience

    View Slide

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

    View Slide

  26. View Slide

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

    View Slide

  28. View Slide

  29. DISTRACT THE USER

    View Slide

  30. Web Performance
    matters!

    View Slide

  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.

    View Slide

  32. Get your business use case!
    WPO stats
    wpostats.com

    View Slide

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

    View Slide

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

    View Slide

  35. - getting started -
    git clone [email protected]:stefanjudis/webperf-101-workshop.git
    npm i
    npm run dev
    git clone [email protected]:stefanjudis/webperf-101-workshop-final.git
    npm i
    npm run dev

    View Slide

  36. View Slide

  37. EXAMPLE SITE
    (BASED ON BOOTSTRAP)
    CHROME DESKTOP
    DSL CONNECTION

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. Measure everything!

    View Slide

  42. WAYS TO MEASURE PERFORMANCE
    Synthetic
    Monitoring
    Real User
    Monitoring

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. - Real User Monitoring -

    View Slide

  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

    View Slide

  51. 01 IMAGE FORMATS

    View Slide

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

    View Slide

  53. TRADITIONAL IMAGE FORMATS
    GIF JPG PNG SVG

    View Slide

  54. Is it a vector graphic?
    YES NO

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  62. 2000×1038

    View Slide

  63. gif – 1.4MB (0.01€)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  67. image formats
    “Are there alternatives?

    View Slide

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

    View Slide

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

    View Slide

  70. webp – 121KB (0.001€)

    View Slide

  71. progressive enhancement






    www.useragentman.com/blog/2015/01/14/using-webp-jpeg2000-jpegxr-apng-now-with-picturefill-and-modernizr/

    View Slide

  72. server side detection

    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]


    Header append Vary Accept env=REDIRECT_accept

    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

    View Slide

  73. server side detection
    .htaccess
    www.igvita.com/posts/12/xbandwidth-vs-latency.png.pagespeed.ic.rKtq8Mdb7q.jpg

    View Slide

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

    View Slide

  75. CODING TIME

    View Slide

  76. 02 IMAGE COMPRESSION

    View Slide

  77. - jpeg quality -

    View Slide

  78. - jpeg compression modes -

    View Slide

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

    View Slide

  80. JPEG ENCODER
    LIBJPEG MOZJPEG GUETZLI

    View Slide

  81. libjpeg – 399KB (0.004€)

    View Slide

  82. guetzli – 336KB (0.003€)

    View Slide

  83. mozjpeg – 197KB (0.002€)

    View Slide

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

    View Slide

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

    View Slide

  86. View Slide

  87. CODING TIME

    View Slide

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

    View Slide

  89. images.guide/

    View Slide

  90. 03 RESPONSIVE IMAGES

    View Slide

  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€)

    View Slide

  92. View Slide

  93. load images responsively
    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">


    View Slide

  94. load images responsively
    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">


    View Slide

  95. all jpeg ~170KB (0.002€)

    View Slide

  96. CODING TIME

    View Slide

  97. 04 VIDEO

    View Slide

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

    View Slide

  99. View Slide

  100. # $ compress_video caniuse.mp4 caniuse_compressed.mp4
    function compress_video() {
    if ! [ $# -eq 2 ]; then
    echo "Wrong parameter usage: \n $ compress_video "
    return 1
    fi
    ffmpeg -i $1 -vcodec h264 -b:v 1000k -acodec mp2 $2
    }
    compress video on the fly

    View Slide

  101. mp4 vs. webm

    View Slide





  102. progressive enhancement

    View Slide

  103. 5.2M share-inbox.mp4 (0.05€)
    1.1M share-inbox_web.mp4 (0.01€)
    515K share-inbox_web.webm (0.005€)
    compression

    View Slide

  104. # $ prepare_video caniuse.mp4 caniuse_compressed
    function prepare_video() {
    if ! [ $# -eq 1 ]; then
    echo "Wrong parameter usage: \n $ compress_video "
    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

    View Slide

  105. Use video
    responsibly

    View Slide

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

    View Slide

  107. 05 TEXT COMPRESSION

    View Slide

  108. twitter.com/dougsillars/status/917464153522102272

    View Slide

  109. gzip

    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
    ...
    ...
    ...

    .htaccess

    View Slide

  110. 2.4M application-97681b5991.min.js (0.02€)
    708K application-97681b5991.min.js.gz (0.007€)
    gzip
    .htaccess

    View Slide

  111. accept-encoding: gzip, deflate, br

    View Slide

  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/

    View Slide

  113. brotli
    caniuse.com/#feat=brotli

    View Slide

  114. 06 CACHING

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  119. caching of static assets

    View Slide

  120. caching of static assets

    View Slide

  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.

    View Slide

  122. code.facebook.com/posts/557147474482256/this-browser-tweak-saved-60-of-requests-to-facebook/

    View Slide

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

    View Slide

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

    View Slide

  125. 07 CONCAT & MINIFY

    View Slide

  126. github.com/mishoo/UglifyJS

    View Slide

  127. github.com/jakubpawlowicz/clean-css

    View Slide

  128. github.com/kangax/html-minifier

    View Slide

  129. CODING TIME

    View Slide

  130. 08 ICONS

    View Slide

  131. ICON FONTS

    View Slide

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

    View Slide

  133. Using SVGs

    load as img
    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">
    ...

    inline SVG
    .element {
    background-image: url(/images/image.svg);
    }
    load SVG in CSS

    View Slide

  134. Using SVGs



    Basketball







    load as an icon system

    View Slide

  135. www.perf-tooling.today/tools

    View Slide

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

    View Slide

  137. CODING TIME

    View Slide

  138. 09 SCRIPT LOADING

    View Slide

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

    View Slide

  140. script loading



    vs
    vs

    View Slide

  141. script loading

    HTML parsing

    View Slide

  142. script loading

    HTML parsing HTML parsing paused HTML parsing
    Script fetch Script execution

    View Slide

  143. script loading

    HTML parsing
    async

    View Slide

  144. script loading

    HTML parsing HTML parsing
    Script fetch Script execution
    async

    View Slide

  145. script loading

    HTML parsing
    defer

    View Slide

  146. script loading

    HTML parsing
    Script fetch Script execution
    defer

    View Slide

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

    View Slide

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

    View Slide

  149. bitsofco.de/async-vs-defer/

    View Slide

  150. script loading
    “Which one do you prefer?

    View Slide

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

    View Slide

  152. SPOF

    View Slide

  153. Without blocking script With blackboxed script

    View Slide

  154. View Slide

  155. View Slide

  156. src="https://seal.websecurity.norton.com/getseal?<br/>host_name=www.thehiddencost.de&amp;lang=de">

    View Slide

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

    View Slide

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

    View Slide

  159. TRUST

    View Slide

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

    View Slide

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

    View Slide

  162. REMOVE, REMOVE, ...

    View Slide

  163. 3rd parties

    View Slide

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

    View Slide

  165. twitter.com/DasSurma/status/915573188398022656

    View Slide

  166. CODING TIME

    View Slide

  167. 10 CRITICAL PATH

    View Slide

  168. critical path

    Get something on the
    screen as soon as possible

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  173. www.igvita.com/2012/07/19/latency-the-new-web-performance-bottleneck/
    latency matters

    View Slide

  174. latency matters

    View Slide

  175. inline critical CSS
    index.html
    main.css

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  179. github.com/filamentgroup/loadCSS

    View Slide

  180. inline critical CSS

    <br/>// critical styles<br/>
    onload="this.rel='stylesheet'">

    <br/>/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */<br/>(function(){ ... }());<br/>/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */<br/>(function(){ ... }());<br/>

    View Slide

  181. github.com/addyosmani/critical

    View Slide

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

    View Slide

  183. 11 UNUSED CODE

    View Slide

  184. View Slide

  185. github.com/giakki/uncss

    View Slide

  186. ANALYSE PACKAGES

    View Slide

  187. View Slide

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

    View Slide

  189. CODING TIME

    View Slide

  190. 12 LAZY LOADING

    View Slide

  191. lazy loading
    “How do you

    implement lazy loading?

    View Slide

  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

    View Slide

  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

    View Slide

  194. WHAT FORCES
    LAYOUT / REFLOW
    gist.github.com/paulirish/5d52fb081b3570c81e3a

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  199. View Slide

  200. View Slide

  201. View Slide

  202. View Slide

  203. Intersection Observer

    View Slide

  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));
    })();

    View Slide

  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));
    })();

    View Slide

  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));
    })();

    View Slide

  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 -

    View Slide

  208. - Intersection Observer -
    caniuse.com/#feat=intersectionobserver
    * in development
    *

    View Slide

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

    View Slide

  210. github.com/ApoorvSaxena/lozad.js

    View Slide

  211. CODING TIME

    View Slide

  212. 13 PRE LOADING

    View Slide

  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/

    View Slide

  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.

    View Slide

  215. www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/

    View Slide

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

    View Slide

  217. www.stefanjudis.com

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  222. Link: ; rel=dns-prefetch
    Link: ; rel=preconnect
    Link: ; rel=prefetch;
    Link: ; rel=preload; as=image;
    Usage




    link element
    header

    View Slide

  223. medium.com/@benschwarz/the-critical-request-90bb47da5769

    View Slide

  224. CODING TIME

    View Slide

  225. 15 FONT LOADING

    View Slide

  226. - font loading behavior -
    FOUT?
    FOIT?

    View Slide

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

    View Slide

  228. - font loading behavior -

    View Slide

  229. FOIT!
    - font loading behavior -

    View Slide

  230. - font loading behavior -
    FOUT FOIT FOIT FOIT FOIT
    3s 3s 3s 3s
    -
    www.zachleat.com/web/fout-foit-history/

    View Slide

  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

    View Slide

  232. css-tricks.com/snippets/css/system-font-stack/

    View Slide

  233. FONTS ON MOBILE?

    View Slide

  234. @media screen and (min-width: 52em) {
    body {
    font-family: 'Droid Sans', sans-serif;
    }
    }
    no fonts for mobile?

    View Slide

  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

    View Slide

  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

    View Slide

  237. - font rendering controls -
    caniuse.com/#feat=css-font-rendering-controls
    *
    * behind a flag

    View Slide

  238. - preload fonts -

    Link: ; rel=preload; as=font;

    View Slide

  239. www.zachleat.com/web/comprehensive-webfonts/

    View Slide

  240. 16 NEW METRICS

    View Slide

  241. new metrics

    What metrics do
    we have today?

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  245. - Navigation Timing API -
    w3c.github.io/navigation-timing/

    View Slide

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

    View Slide

  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')

    View Slide

  248. [...Array(20)].forEach(cornify_add);
    - User Timing API -
    w3c.github.io/user-timing/
    if (talksSeen === nrOfTalks) {
    }

    View Slide

  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'
    );
    }

    View Slide

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

    View Slide

  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
    },
    ...
    ]

    View Slide

  252. ENTRY TYPE VALUES
    mark measure navigation resource
    ACCESSIBLE VIA
    getEntries getEntriesByType getEntriesByName

    View Slide

  253. GOOD METRICS

    View Slide

  254. - Speed Index -

    View Slide

  255. - Speed Index -

    View Slide

  256. src="hero.jpg"
    onload="performance.clearMarks('img displayed');
    performance.mark('img displayed');">
    <br/>performance.clearMarks("img displayed");<br/>performance.mark("img displayed");<br/>
    speedcurve.com/blog/user-timing-and-custom-metrics/
    - custom metrics -

    View Slide

  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')

    View Slide

  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')

    View Slide

  259. - Performance Observer -
    developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver
    *
    * behind a flag

    View Slide

  260. View Slide

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

    View Slide

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

    View Slide

  263. 17 HTTP/2

    View Slide

  264. www.httpvshttps.com/

    View Slide

  265. www.httpvshttps.com/

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  269. PUSH?

    View Slide

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

    View Slide

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

    View Slide

  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.

    View Slide

  273. tools.ietf.org/html/draft-ietf-httpbis-cache-digest-00

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  278. engineering.khanacademy.org/posts/js-packaging-http2.htm

    View Slide

  279. ALWAYS MEASURE!

    View Slide

  280. hpbn.co/

    View Slide

  281. 18 BUDGETING

    View Slide

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

    View Slide

  283. BIZ HAS TO BE ON BOARD

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  288. - performance budget -

    What is a good budget?

    View Slide

  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
    ...

    View Slide

  290. - performance budget -
    “You decide!

    View Slide

  291. What happens if something
    does not fit within the budget?
    Steve Souders
    Speedcurve
    Optimize?
    Remove?
    Don't do it?

    View Slide

  292. www.perf-tooling.today/tools?q=budget

    View Slide

  293. STILL TIME?

    View Slide

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

    View Slide

  295. Web Performance is
    the art of doing less

    but then in a smarter way.

    View Slide

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

    View Slide