Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WCEU: Seven Times Faster : A Study in frontend Optimization

WCEU: Seven Times Faster : A Study in frontend Optimization

The average web page takes fifteen seconds to load, this can lower the PageSpeed score to the low 30s. Working together web designers and devs can make sites readable in two seconds, working towards a web seven times faster.

Find out how to get a PageSpeed score in the 90s. What are the rules you have to follow, what are those you have to break?

Peter Wilson

June 24, 2016
Tweet

More Decks by Peter Wilson

Other Decks in Technology

Transcript

  1. Wed 29 Oct 1969
    ~ ucla$ ░

    View full-size slide

  2. Wed 29 Oct 1969
    ~ ucla$ ░

    View full-size slide

  3. Wed 29 Oct 1969
    ~ ucla$ lo ░
    gin

    View full-size slide

  4. Wed 29 Oct 1969
    ~ ucla$ lo ░

    View full-size slide

  5. Seven times faster: 

    a study in front-end optimisation
    Peter Wilson • peterwilson.cc • @pwcc

    View full-size slide

  6. WordPress is slow

    View full-size slide

  7. Front-end code is slow

    View full-size slide

  8. Bytes on the page

    View full-size slide

  9. Total page size (MB)
    Nov 2011 - March 2016
    0.5
    1.0
    1.5
    2.0
    2.5
    1 Nov '11 15 May '12 1 Dec '12 15 Jun '13 1 Jan '14 15 Jul '14 1 Feb '15 15 Aug '15 1 Mar '16
    httparchive.org/trends.php, March 2016

    View full-size slide

  10. Assets per page
    Nov 2011 - March 2016
    20
    40
    60
    80
    100
    120
    1 Nov '11 15 May '12 1 Dec '12 15 Jun '13 1 Jan '14 15 Jul '14 1 Feb '15 15 Aug '15 1 Mar '16
    httparchive.org/trends.php, March 2016

    View full-size slide

  11. Webfonts
    Multiple of Nov 2011 (bytes)
    2
    4
    6
    8
    10
    12
    14
    16
    18
    1 Nov '11 15 May '12 1 Dec '12 15 Jun '13 1 Jan '14 15 Jul '14 1 Feb '15 15 Aug '15 1 Mar '16
    httparchive.org/trends.php, March 2016

    View full-size slide

  12. Load time
    httparchive.org/trends.php, March 2016

    View full-size slide

  13. Load time
    Start render: 4.2 seconds

    View full-size slide

  14. Load time
    Visually complete: 12.7 seconds

    View full-size slide

  15. Load time
    Document complete: 15.23 sec

    View full-size slide

  16. Walmart conversion rate
    slideshare.net/devonauerswald/walmart-pagespeedslide
    0 - 1
    1 - 2
    2 - 3
    3 - 4
    4 - 5
    5 - 6
    6 - 7
    7 - 8
    8 - 9
    9 - 10
    10 - 11
    11 - 12
    12 - 13
    13 - 14
    14 - 15
    15+

    View full-size slide

  17. The average site kills conversions.

    View full-size slide

  18. Measure a starting point

    View full-size slide

  19. WebPageTest - webpagetest.org

    View full-size slide

  20. Key metrics
    Document Complete Fully Loaded
    Load Time First Byte Start Render Speed Index
    DOM
    Elements
    Time Requests Bytes In Time Requests Bytes In
    3.770s 0.771s 1.789s 1834 397 3.770s 27 635 KB 4.072s 33 661 KB
    WebPageTest - webpagetest.org

    View full-size slide

  21. Timeline view

    View full-size slide

  22. Comparison timelines
    Additional blocking request in HTML Header
    Timed using WebPageTest - pwcc.cc/wceu/blocking
    0.5s 1.0s 1.5s 2.0s
    0% 0% 0% 100%
    0% 86% 100%
    Blocked
    Unblocked

    View full-size slide

  23. 53 / 100
    Our PageSpeed score is
    you won’t believe how

    much it’s costing

    View full-size slide

  24. What will get my visitors
    reading quickest?


    View full-size slide

  25. Doing it wrong

    View full-size slide

  26. JavaScript in the footer

    View full-size slide

  27. All visitors have JavaScript
    disabled while it downloads.
    – Every progressive enhancement advocate ever


    View full-size slide

  28. wp_enqueue_script(
    'pwcc-scripts', // handle
    '/functions.js', // source
    null, // no dependancies
    '20160624-26', // version
    true // load in footer
    );
    JavaScript, the WordPress way

    View full-size slide

  29. wp_enqueue_script(
    'pwcc-scripts', // handle
    '/functions.js', // source
    null, // no dependancies
    '20160624-26', // version
    true // load in footer
    );
    true // load in footer
    JavaScript, the WordPress way

    View full-size slide

  30. wp_enqueue_script(
    'pwcc-scripts', // handle
    '/functions.js', // source
    array( 'jquery' ), // jQuery loads automatically
    '20160624-26', // version
    true // load in footer
    );
    jQuery, the WordPress way

    View full-size slide

  31. wp_enqueue_script(
    'pwcc-scripts', // handle
    '/functions.js', // source
    array( 'jquery' ), // jQuery loads automatically
    '20160624-26', // version
    true // load in footer
    );
    array( 'jquery' ), // jQuery loads automatically
    jQuery, the WordPress way

    View full-size slide









  32. jQuery, doing_it_wrong()

    View full-size slide











  33. jQuery, doing_it_wrong()

    View full-size slide

  34. The WordPress way blocks rendering
    Daniel Zedda (CC) - flic.kr/p/a6wwAh

    View full-size slide

  35. function pwcc_jquery_to_footer() {
    if ( is_admin() )
    return;
    wp_script_add_data( 'jquery', 'group', 1 );
    wp_script_add_data( 'jquery-core', 'group', 1 );
    wp_script_add_data( 'jquery-migrate', 'group', 1 );
    }
    add_action( 'wp', 'pwcc_jquery_to_footer' );
    jQuery, doing_it_wrong()

    View full-size slide

  36. function pwcc_jquery_to_footer() {
    if ( is_admin() )
    return;
    wp_script_add_data( 'jquery', 'group', 1 );
    wp_script_add_data( 'jquery-core', 'group', 1 );
    wp_script_add_data( 'jquery-migrate', 'group', 1 );
    }
    add_action( 'wp', 'pwcc_jquery_to_footer' );
    wp_script_add_data( 'jquery', 'group', 1 );
    wp_script_add_data( 'jquery-core', 'group', 1 );
    wp_script_add_data( 'jquery-migrate', 'group', 1 );
    jQuery, doing_it_wrong()

    View full-size slide

  37. function pwcc_jquery_to_footer() {
    if ( is_admin() )
    return;
    wp_script_add_data( 'jquery', 'group', 1 );
    wp_script_add_data( 'jquery-core', 'group', 1 );
    wp_script_add_data( 'jquery-migrate', 'group', 1 );
    }
    add_action( 'wp', 'pwcc_jquery_to_footer' );
    wp_script_add_data( 'jquery', 'group', 1 );
    wp_script_add_data( 'jquery-core', 'group', 1 );
    wp_script_add_data( 'jquery-migrate', 'group', 1 );
    jQuery, doing_it_wrong()

    View full-size slide









  38. jQuery, the WordPress way

    View full-size slide









  39. jQuery, doing_it_wrong()

    View full-size slide










  40. jQuery, doing_it_wrong()
    pwcc.cc/wceu/jqueryfooter

    View full-size slide

  41. Asynchronous JavaScript

    View full-size slide

  42. Asynchronous JavaScript
    type='text/javascript'
    src='/path/file.js' async>

    View full-size slide

  43. Asynchronous JavaScript
    type='text/javascript'
    src='/path/file.js' async>
    async

    View full-size slide

  44. function pwcc_async_js( $tag, $handle ) {
    switch ( $handle ) {
    case 'pwcc-scripts' :
    $tag = str_replace( '>}
    return $tag;
    }
    Asynchronous JavaScript

    View full-size slide

  45. function pwcc_async_js( $tag, $handle ) {
    switch ( $handle ) {
    case 'pwcc-scripts' : // Falls through
    case 'picturefill' :
    $tag = str_replace( '>}
    return $tag;
    }
    Asynchronous JavaScript

    View full-size slide

  46. function pwcc_async_js( $tag, $handle ) {
    switch ( $handle ) {
    case 'pwcc-scripts' : // Falls through
    case 'picturefill' :
    $tag = str_replace( '>}
    return $tag;
    }
    Asynchronous JavaScript

    View full-size slide

  47. switch ( $handle ) {
    case 'pwcc-scripts' : // Falls through
    case 'picturefill' :
    $tag = str_replace( '>}
    return $tag;
    }
    add_filter( 'script_loader_tag', 'pwcc_async_js', 10, 2 );
    Asynchronous JavaScript

    View full-size slide

  48. function pw_async_up() {
    wp_script_add_data( 'picturefill', 'group', 0 );
    wp_script_add_data( 'pwcc-scripts', 'group', 0 );
    }
    add_action( 'wp_enqueue_scripts', 'pw_async_up' , 99 );
    Asynchronous JS in the header

    View full-size slide

  49. function pw_async_up() {
    wp_script_add_data( 'picturefill', 'group', 0 );
    wp_script_add_data( 'pwcc-scripts', 'group', 0 );
    }
    add_action( 'wp_enqueue_scripts', 'pw_async_up' , 99 );
    Asynchronous JS in the header
    pwcc.cc/wceu/asyncjs

    View full-size slide

  50. Browsers initiate requests
    The blocking nature of HTTP 1

    View full-size slide

  51. Blockers
    HTML

    View full-size slide

  52. Blockers
    HTML
    CSS

    View full-size slide

  53. Blockers
    HTML
    CSS

    View full-size slide

  54. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    FONTS

    View full-size slide

  55. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    FONTS

    View full-size slide

  56. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View full-size slide

  57. Waterfall
    WebPageTest - webpagetest.org

    View full-size slide

  58. Waterfall
    WebPageTest - webpagetest.org

    View full-size slide

  59. Waterfall
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View full-size slide

  60. Waterfall
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View full-size slide

  61. HTTP/2
    An aside

    View full-size slide

  62. Everything you know about
    performance is now wrong and
    former best practices are now an
    anti-pattern and considered
    harmful.

    View full-size slide

  63. These titles are
    considered harmful

    View full-size slide

  64. Sites using HTTP/2
    w3techs.com, March 2016

    View full-size slide

  65. caniuse.com/http2, March 2016

    View full-size slide

  66. caniuse.com/http2, March 2016

    View full-size slide

  67. Critical Path CSS

    View full-size slide

  68. w3.org/TR/preload/

    View full-size slide

  69. HTTP/2, without critical path CSS
    HTML
    CSS

    View full-size slide

  70. HTTP/1, with critical path CSS
    HTML
    CSS

    View full-size slide



  71. html{font-family:sans-serif;-ms-text-size-adjust:<br/>100%;-webkit-text-size-adjust:100%}body{margin:0}article,<br/>aside,details,figcaption,figure,footer,header,hgroup,main,<br/>nav,section,summary{display:block}audio,canvas,progress,<br/>video{display:inline-block;vertical-align:baseline}<br/>audio:not([controls]){display:none;height:0}[hidden],<br/>template{display:none}a{background:transparent}a:active,<br/>a:hover{outline:0}abbr[title]{border-bottom:1px dotted}<br/>b,strong{font-weight:bold}dfn{font-style:italic}h1{font-<br/>

    View full-size slide

  72. HTTP/1, with critical path CSS
    HTML
    CSS

    View full-size slide

  73. HTTP/1, without critical path CSS
    HTML
    CSS

    View full-size slide

  74. CSS, the WordPress way
    wp_enqueue_style(
    'pwcc-style', // handle
    get_stylesheet_uri(), // source
    array(), // no dependancies
    '20160624-26', // version
    'all' // media
    );

    View full-size slide

  75. Preloading CSS

    View full-size slide

  76. Preloading CSS

    View full-size slide

  77. Preloading CSS
    Link: ; rel=preload; as=style; nopush

    View full-size slide

  78. Preloading CSS
    Link: ; rel=preload; as=style; nopush

    View full-size slide

  79. Preloading CSS
    pwcc_preload_style( 'pwcc-style' ); // push
    pwcc_preload_style( 'pwcc-style', false ); // no push

    View full-size slide

  80. Server push
    pwcc_preload_style( 'pwcc-style' );

    View full-size slide

  81. Server push
    if ( is_cached( 'pwcc-style' ) ) {
    pwcc_preload_style( 'pwcc-style' );
    } else /* file not cached */ {
    pwcc_preload_style( 'pwcc-style', false );
    }

    View full-size slide

  82. $version = '20160624-26';
    setcookie( 'pwcc-style', $version, 0, '/' );
    Server push

    View full-size slide

  83. is_cached()
    function is_cached( $handle, $version ) {
    if ( $version === $_COOKIE[ $handle ] ) {
    return true;
    }
    else {
    return false;
    }
    }

    View full-size slide



  84. html{font-family:sans-serif;-ms-text-size-adjust:<br/>100%;-webkit-text-size-adjust:100%}body{margin:0}article,<br/>aside,details,figcaption,figure,footer,header,hgroup,main,<br/>nav,section,summary{display:block}audio,canvas,progress,<br/>video{display:inline-block;vertical-align:baseline}<br/>audio:not([controls]){display:none;height:0}[hidden],<br/>template{display:none}a{background:transparent}a:active,<br/>a:hover{outline:0}abbr[title]{border-bottom:1px dotted}<br/>b,strong{font-weight:bold}dfn{font-style:italic}h1{font-<br/>

    View full-size slide

  85. pwcc.cc/wceu/loadcss

    View full-size slide

  86. Register loadCSS
    wp_register_script(
    'pwcc-load-css', // handle
    '/loadcss.js', // file
    array(), // dependencies
    "1.2.0", // version
    true // load in footer
    );

    View full-size slide

  87. /* Critical CSS */
    as='style' onload='this.rel="stylesheet"'>



    HTML: uncached HTTP/1

    View full-size slide

  88. if ( ! is_cached( 'pwcc-style' ) && ! is_http2() ) {
    print_style_inline( 'pwcc-style' );
    wp_enqueue_script( 'pwcc-load-css' );
    }
    Inline CSS

    View full-size slide

  89. if ( ! is_cached( 'pwcc-style' ) && ! is_http2() ) {
    print_style_inline( 'pwcc-style' );
    wp_enqueue_script( 'pwcc-load-css' );
    }
    Inline CSS
    pwcc.cc/wceu/rapidcss

    View full-size slide



  90. html{font-family:sans-serif;-ms-text-size-adjust:<br/>100%;-webkit-text-size-adjust:100%}body{margin:0}article,<br/>aside,details,figcaption,figure,footer,header,hgroup,main,<br/>nav,section,summary{display:block}audio,canvas,progress,<br/>video{display:inline-block;vertical-align:baseline}<br/>audio:not([controls]){display:none;height:0}[hidden],<br/>template{display:none}a{background:transparent}a:active,<br/>a:hover{outline:0}abbr[title]{border-bottom:1px dotted}<br/>b,strong{font-weight:bold}dfn{font-style:italic}h1{font-<br/>

    View full-size slide


  91. Cached Stylesheet

    View full-size slide

  92. Everything you know about
    performance is now wrong and
    former best practices are now an
    anti-pattern and considered
    harmful.

    View full-size slide

  93. Everything you know about
    performance is now
    twice as complicated.

    View full-size slide

  94. Thank you
    Peter Wilson • peterwilson.cc • @pwcc

    View full-size slide