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

[CodeDaze 2016] Every Millisecond Counts: Performance & UX

Davey Shafik
September 15, 2016

[CodeDaze 2016] Every Millisecond Counts: Performance & UX

How do you lose 900 million dollars in 100ms? Or 8 million visits in just 4/10 of a second?

User expectations are higher than ever when it comes to web performance, so much so that we've created an entirely new application architecture just to make it feel like our websites are faster than they actually are.

This talk will look at how we can improve our users experience at any scale through performance optimizations at every layer of the stack, from backend to browser.

Davey Shafik

September 15, 2016
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. E V E R Y M I L L I S E CO N D CO U N TS
    P E R F O R M A N C E A N D U S E R E X P E R I E N C E

    View Slide

  2. D AV E Y S H A F I K
    • Developer
    • Author
    • Open Source Contributor
    • Release Manager for PHP 7.1
    • @dshafik

    View Slide

  3. http://developer.akamai.com

    View Slide

  4. Let’s start a conversation about
    mental health in tech
    mhprompt.org

    View Slide

  5. W H Y P E R FO R M A N C E M AT T E RS
    CC-BY-ND 2.0: Raymond June

    View Slide

  6. A M A ZO N
    CC-BY 2.0: Thomas Shahan

    View Slide

  7. LO S E S 1 % O F R E V E N U E P E R 1 0 0 M S
    S O U R C E : H T T P : / / R A D A R . O R E I L LY. C O M / 2 0 0 8 / 0 8 / R A D A R - T H E M E - W E B - O P S . H T M L

    View Slide

  8. $ 1 , 0 7 0 , 0 0 0 , 0 0 0
    2 0 1 5

    View Slide

  9. 1 5 ¢ F O R E V E R Y S I N G L E P E RS O N O N
    E A RT H
    2 0 1 5

    View Slide

  10. $ 3 . 3 2 P E R US C I T I Z E N
    2 0 1 5

    View Slide

  11. R E M I N D E R : P E R 1 0 0 M S S LO W E R !

    View Slide

  12. G O O G L E
    CC-BY: Robert Scoble

    View Slide

  13. 0 . 5 S S LO W E R = 2 0 % L E SS S E A R C H E S
    S O U R C E : H T T P : / / G L I N D E N . B L O G S P O T. C O M / 2 0 0 6 / 1 1 / M A R I S S A - M A Y E R - A T- W E B - 2 0 . H T M L

    View Slide

  14. B I N G
    CC-BY-SA 2.0: badgreeb RECORDS

    View Slide

  15. 2 S S LO W E R = - 4 . 3 % R E V E N U E / U S E R
    S O U R C E : H T T P : / / V E L O C I T Y C O N F. C O M / V E L O C I T Y 2 0 0 9 / P U B L I C / S C H E D U L E / D E TA I L / 8 5 2 3

    View Slide

  16. G Q
    CC-BY 2.0: BIAU Guillaume

    View Slide

  17. CU T LOA D T I M E BY 8 0 % :
    T R A F F I C + 8 0 % & T I M E S P E N T + 3 2 %
    S O U R C E : H T T P : / / D I G I D AY. CO M / P U B L I S H E RS /G Q - CO M - CU T- PA G E - LOA D -T I M E - 8 0 - P E R C E N T/

    View Slide

  18. M O R E

    View Slide

  19. • WALMART: 1s improvement = 2% increase in conversions
    • ETSY: +160KB of images mobile site = 12% increase in bounce rate
    • STAPLES: 1s improvement = 10% increase in conversions
    S O U R C E : H T T P : / / W W W. S L I D E S H A R E . N E T/C L I F FC R O C K E R / V E LO C I TY- N Y- H O W-TO - M E A S U R E -
    R E V E N U E - I N - M I L L I S E CO N D S
    S O U R C E : H T T P : / / R A D A R . O R E I L LY. CO M / 2 0 1 4 / 0 1 / W E B - P E R FO R M A N C E - I S - US E R- E X P E R I E N C E . H T M L
    S O U R C E : H T T P : / / W W W. S L I D E S H A R E . N E T/ D E VO N AU E RS W A L D/ W A L M A RT- PA G E S P E E D S L I D E

    View Slide

  20. CO N C LUS I O N

    View Slide

  21. U S E RS C A N P E R C E I V E T I N Y
    C H A N G E S I N P E R FO R M A N C E
    A S L I T T L E A S 1 4 M S

    View Slide

  22. S LO W E R S I T E S M A K E
    CUSTO M E RS L E SS H A P P Y

    View Slide

  23. L E SS H A P PY = P O O R US E R E X P E R I E N C E

    View Slide

  24. YO U P R O B A B LY N OT I C E D I T
    YO U RS E L F…

    View Slide

  25. 1 0 S E CO N D S I S A N E T E R N I TY

    View Slide

  26. M O B I L E : 5 3 % B O U N C E A F T E R 3 S
    S O U R C E : H T T P S : / / W W W. S OA STA . CO M / B LO G /G O O G L E - M O B I L E -W E B - P E R F O R M A N C E -ST U DY/

    View Slide

  27. W H O I S R E S P O N S I B L E FO R P E R FO R M A N C E ?
    CC-BY 2.0: davetoaster

    View Slide

  28. E V E R YO N E !
    CC-BY 2.0: James Cridland

    View Slide

  29. E V E R YO N E !
    • Designers
    • Sysadmins/Devops
    • Backend Developers
    • Frontend Developers
    • Browser Vendors

    View Slide

  30. W H AT M A K E S A W E B PA G E ?
    CC-BY-SA 2.0: Susanne Nilsson

    View Slide

  31. TOTA L PA G E W E I G H T D I ST R I B U T I O N
    HTTP Archive – September 2015
    http://httparchive.org/trends.php
    Fonts
    5%
    CSS
    3%
    JS
    17%
    HTML
    3%
    Images
    63%
    Other
    9%

    View Slide

  32. TOTA L PA G E W E I G H T ( M B )
    0-1MB 1-2MB 2-3MB 3-4MB 4-5MB 5-6MB 6-8MB
    3%
    2%
    4%
    8%
    15%
    28%
    36%

    View Slide

  33. TOTA L R E Q U E STS P E R PA G E
    1-25 26-50 51-75 76-100 101-125 126-150 > 150
    15%
    8%
    12%
    16%
    18%
    16%
    11%

    View Slide

  34. D E S I G N E RS
    CC-BY 2.0: Cliff Hutson

    View Slide

  35. CO M P R E SS YO U R I M AG E S

    View Slide

  36. CO M P R E SS YO U R I M AG E S
    ( O R D E V E LO P E RS W I L L D O I T FO R YO U ! )

    View Slide

  37. SYS A D M I N S / D E V O P S
    CC-BY-SA 2.0: Bjorn Watland

    View Slide

  38. E N A B L E H T T P/ 2

    View Slide

  39. L E T ’ S E N C R Y PT !
    CC-BY: Jason Baker

    View Slide

  40. L E TS E N C R Y PT. O R G
    Attribution

    View Slide

  41. L E TS E N C R Y PT. O R G
    • Free (as in beer)
    • Automatic
    • Secure
    • Transparent
    • Open
    • Cooperative

    View Slide

  42. U S E T H E C LO U D TO S C A L E B A S E D 

    O N P E R C E I V E D P E R F O R M A N C E
    CC-BY 2.0: Steve Jurvetson

    View Slide

  43. S C A L E D B A S E D O N P E R C E I V E D P E R F O R M A N C E
    • Resource usage doesn’t tell you the whole story
    • Use SpeedIndex scores as an additional metric to determine
    scaling thresholds
    • Use marcelduran / webpagetest-api (node)

    View Slide

  44. var WebPageTest = require('webpagetest');
    var http = require('http');
    var wpt = new WebPageTest('www.webpagetest.org', 'KEY HERE');
    wpt.runTest('https://daveyshafik.com', {pageSpeed: true}, function(err, data) {
    console.log("Test results at: " + data.data.jsonUrl);
    checkResponse(data.data.jsonUrl);
    });
    function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  45. var WebPageTest = require('webpagetest');
    var http = require('http');
    var wpt = new WebPageTest('www.webpagetest.org', 'KEY HERE');
    wpt.runTest('https://daveyshafik.com', {pageSpeed: true}, function(err, data) {
    console.log("Test results at: " + data.data.jsonUrl);
    checkResponse(data.data.jsonUrl);
    });
    function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);

    View Slide

  46. var WebPageTest = require('webpagetest');
    var http = require('http');
    var wpt = new WebPageTest('www.webpagetest.org', 'KEY HERE');
    wpt.runTest('https://daveyshafik.com', {pageSpeed: true}, function(err, data) {
    console.log("Test results at: " + data.data.jsonUrl);
    checkResponse(data.data.jsonUrl);
    });
    function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);

    View Slide

  47. var WebPageTest = require('webpagetest');
    var http = require('http');
    var wpt = new WebPageTest('www.webpagetest.org', 'KEY HERE');
    wpt.runTest('https://daveyshafik.com', {pageSpeed: true}, function(err, data) {
    console.log("Test results at: " + data.data.jsonUrl);
    checkResponse(data.data.jsonUrl);
    });
    function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);

    View Slide

  48. var WebPageTest = require('webpagetest');
    var http = require('http');
    var wpt = new WebPageTest('www.webpagetest.org', 'KEY HERE');
    wpt.runTest('https://daveyshafik.com', {pageSpeed: true}, function(err, data) {
    console.log("Test results at: " + data.data.jsonUrl);
    checkResponse(data.data.jsonUrl);
    });
    function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);

    View Slide

  49. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  50. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  51. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  52. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  53. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  54. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  55. function checkResponse(reportUrl)
    {
    http.get(reportUrl, function(response) {
    var responseData = '';
    response.on('data', function(data) {
    responseData += data;
    });
    response.on('end', function() {
    var data = JSON.parse(responseData);
    if (data.statusCode == 200) {
    console.log("First view: " + data.data.average.firstView.SpeedIndex);
    console.log("Repeat view: " + data.data.average.repeatView.SpeedIndex);
    } else {
    console.log(data.statusText);
    setTimeout(function () { checkResponse(reportUrl); }, 5000);
    }
    });
    });
    }

    View Slide

  56. View Slide

  57. B A C K E N D D E V E LO P E RS
    CC-BY 2.0: Bobo Boom

    View Slide

  58. C A C H E A G G R E S S I V E LY
    CC-BY: Travis Wise

    View Slide

  59. D ATA B A S E C AC H I N G

    View Slide

  60. D ATA B A S E C AC H I N G
    • Memcache
    • Cassandra

    View Slide

  61. F U L L PAG E C AC H I N G

    View Slide

  62. F U L L PA G E C A C H I N G
    • Memcache
    • Cassandra
    • Varnish
    • Squid

    View Slide

  63. E D G E S I D E I N C LU D E S
    ( E S I )

    View Slide

  64. E D G E S I D E I N C LU D E S
    • Created by Akamai (and some other companies)
    • Partially supported by Varnish, Squid, and others
    • Uses special HTML tags to cache fragments of pages differently
    than rest of the page
    • e.g. no caching, different TTL, per user session, or per geographic area

    View Slide

  65. E X A M P L E E D G E S I D E I N C LU D E : LO G I N


    Hello!

    View Slide

  66. E X A M P L E E D G E S I D E I N C LU D E : LO G I N


    Hello!

    View Slide



  67. Hello!

    E X A M P L E E D G E S I D E I N C LU D E : LO G I N

    View Slide



  68. Hello!

    E X A M P L E E D G E S I D E I N C LU D E : LO G I N

    View Slide

  69. I M AG E S

    View Slide

  70. F O R M AT N E G OT I AT I O N

    View Slide

  71. J P E G X R
    W E B P
    ɂ Ʌɚ

    View Slide

  72. CO M P R E SS I O N

    View Slide

  73. J P E G L E V E LS : 0 - 1 0 0

    View Slide

  74. J P E G L E V E LS : 0 - 1 0 0
    T H E Y ’ R E W H AT E V E R T H E E N CO D E R W A N TS T H E M TO M E A N

    View Slide

  75. P E R C E I V E D Q UA L I TY

    View Slide

  76. Q UA L I TY H U M A N S C A N S E E
    P E R C E I V E D Q UA L I TY

    View Slide

  77. View Slide

  78. View Slide

  79. O R I G I N A L : 1 6 . 8 M B

    View Slide

  80. 9 0 : 5 . 8 M B

    View Slide

  81. 8 0 : 4 . 2 M B

    View Slide

  82. 7 0 : 3 . 2 M B

    View Slide

  83. 6 0 : 2 . 5 M B

    View Slide

  84. 5 0 : 1 . 9 M B

    View Slide

  85. 4 0 : 1 . 4 M B

    View Slide

  86. 3 0 : 1 . 2 M B

    View Slide

  87. 2 0 : 9 5 0 K B

    View Slide

  88. 1 0 : 5 9 4 K B

    View Slide

  89. 0 : 3 9 3 K B

    View Slide

  90. O R I G I N A L

    View Slide

  91. 0

    View Slide

  92. SS I M
    S T R U CT U R A L S I M I L A R I TY I M AG E

    View Slide

  93. E M M Y A W A R D W I N N I N G A LG O R I T H M
    Zhou Wang, Alan C. Bovik, Hamid R. Sheikh, and Eero P. Simoncelli

    View Slide

  94. SS I M A LG O R I T H M
    • Brightness
    • Contrast
    • Structure
    • Fast

    View Slide

  95. D SS I M
    ST R U CT U R A L D I SS I M I L A R I TY: D I STA N C E M E T R I C D E R I V E D F R O M SS I M

    View Slide

  96. AUTOPLAY

    View Slide

  97. View Slide

  98. 0.009273 /images/90.png
    0.008136 /images/80.png
    0.009007 /images/70.png
    0.010287 /images/60.png
    0.012078 /images/50.png
    0.014768 /images/40.png
    0.017413 /images/30.png
    0.020712 /images/20.png
    0.028642 /images/10.png
    0.038585 /images/0.png

    View Slide

  99. P E R C E PT I V E Q UA L I TY T H R E S H O L D

    View Slide

  100. Original: 14.1MB 80: 0.008136 4.6MB
    30: 0.017413 1.2MB
    50: 0.012078 1.9MB

    View Slide

  101. -91.4%

    View Slide

  102. F R O N T E N D D E V E LO P E RS
    CC-BY 2.0: Bill Jacobus

    View Slide

  103. P R E D I CT I V E B R O W S I N G

    View Slide

  104. P R E B R O W S I N G

    View Slide

  105. P R E B R O W S I N G
    1. DNS Prefetch
    2. TCP Preconnect
    3. Prefetch
    4. Prerender

    View Slide

  106. Ɇ
    ɂ

    View Slide

  107. D N S P R E F E TC H
    ɐ
    Ɇ
    ɂ
    10.0.0.1
    127.0.0.1

    View Slide

  108. TC P P R E CO N N E CT
    ɐ
    Ɇ Ȑ
    ɂ
    10.0.0.1
    127.0.0.1

    View Slide

  109. P R E LOA D
    ɐ
    Ɇ Ȑ
    ɂ
    10.0.0.1
    127.0.0.1

    View Slide

  110. P R E R E N D E R
    ɐ
    Ɇ Ȑ

    ɂ
    10.0.0.1
    127.0.0.1

    View Slide

  111. D N S P R E F E TC H

    View Slide




  112. D N S P R E F E TC H

    View Slide




  113. D N S P R E F E TC H

    View Slide




  114. D N S P R E F E TC H

    View Slide




  115. D N S P R E F E TC H

    View Slide



  116. P R E CO N N E CT

    View Slide




  117. P R E F E TC H

    View Slide




  118. P R E F E TC H

    View Slide




  119. P R E R E N D E R

    View Slide

  120. W A R N I N G !
    CC-BY 2.0: Robert Couse-Baker

    View Slide

  121. 1-25 26-50 51-75 76-100 101-125 126-150 > 150
    15%
    8%
    12%
    16%
    18%
    16%
    11%
    0-1MB 1-2MB 2-3MB 3-4MB 4-5MB 5-6MB 6-8MB
    3%
    2%
    4%
    8%
    15%
    28%
    36%
    Fonts
    5%
    CSS
    3%
    JS
    17%
    HTML
    3%
    Images
    63%
    Other
    9%
    YO U H AV E TO R E N D E R T H E E N T I R E PAG E !

    View Slide

  122. R E L = P R E LOA D

    View Slide

  123. P R E F E TC H VS P R E LO A D

    View Slide

  124. P R E LOA D V S P R E F E TC H
    • prefetch is an optional and low-priority fetch for a resource that
    might be used by a subsequent navigation
    • preload is a mandatory and high-priority fetch for a resource that
    is necessary for the current navigation
    • preload is typically sent as a header, rather than a tag

    View Slide

  125. L I N K H E A D E R
    Link: /resource; rel=preload

    View Slide

  126. N E W A R C H I T E CT U R E S

    View Slide

  127. H T T P/ 1 . X S U C K S
    CC-BY: Flóra Soós

    View Slide

  128. H T T P/ 1 . X S U C K S
    • Minify + Concat JavaScript and CSS
    • Inlining small JavaScript and CSS
    • Using image sprites
    • Using data: URIs
    • Domain sharding

    View Slide

  129. T H E S E T H I N G S A R E A L L " C L E V E R " H AC K S
    CC-BY: Matt Biddulph

    View Slide

  130. M U LT I P L E X I N G
    CC-BY: Alosh Bennett
    C A N U S E O N E C O N N E C T I O N F O R
    P A R A L L E L R E Q U E S T S

    View Slide

  131. S E R V E R P US H
    CC-BY: Steven Depolo

    View Slide

  132. D E P E N D E N C I E S
    CC-BY-SA 2.0: David Gamez

    View Slide

  133. W E I G H TS
    CC-BY 2.0: Tri Vu Dao

    View Slide

  134. D E L I V E R I N G A PAG E

    View Slide

  135. PAG E A SS E TS
    Ɇ
    ɂ
    Ȑ

    View Slide

  136. PAG E A SS E TS
    Ɇ
    ɂ
    Ȑ

    View Slide

  137. PAG E A SS E TS
    GET /index.html
    Ɇ
    ɂ
    Ȑ

    View Slide

  138. PAG E A SS E TS
    GET /index.html
    200 OK text/html
    Ɇ
    ɂ
    Ȑ

    View Slide

  139. PAG E A SS E TS
    Ɇ Ȑ
    ɂ
    GET /index.html
    200 OK text/html

    View Slide

  140. PAG E A SS E TS
    Ɇ Ȑ
    ɂ
    GET /index.html
    200 OK text/html
    critical-path.css
    critical-path.js
    logo.svg

    View Slide

  141. PAG E A SS E TS
    Ɇ Ȑ
    ɂ
    GET /index.html
    200 OK text/html
    critical-path.css
    critical-path.js
    logo.svg
    font.eot

    View Slide

  142. PAG E A SS E TS
    Ɇ Ȑ
    ɂ
    GET /index.html
    200 OK text/html
    critical-path.css
    critical-path.js
    logo.svg
    font.eot
    main.js

    View Slide

  143. PAG E A SS E TS
    Ɇ Ȑ
    ɂ
    GET /index.html
    200 OK text/html
    critical-path.css
    critical-path.js
    logo.svg
    font.eot styles.css
    main.js

    View Slide

  144. I N S U M M A R Y

    View Slide

  145. P E R F O R M A N C E M AT T E RS

    View Slide

  146. T I M E = M O N E Y

    View Slide

  147. T I M E = U S E R S AT I S FA CT I O N = M O N E Y

    View Slide

  148. P E R F O R M A N C E = US E R E X P E R I E N C E

    View Slide

  149. F E E D B A C K & Q U E S T I O N S
    Twitter:
    Email:
    Slides:
    @dshafik
    [email protected]
    http://daveyshafik.com/slides

    View Slide