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 Slide

  2. Wed 29 Oct 1969
    ~ ucla$ ░

    View Slide

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

    View Slide

  4. Wed 29 Oct 1969
    ~ ucla$ lo ░

    View Slide

  5. Seven times faster: 

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

    View Slide

  6. View Slide

  7. WordPress is slow

    View Slide

  8. Front-end code is slow

    View Slide

  9. Bytes on the page

    View Slide

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

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

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

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

    View Slide

  14. Load time
    Start render: 4.2 seconds

    View Slide

  15. Load time
    Visually complete: 12.7 seconds

    View Slide

  16. Load time
    Document complete: 15.23 sec

    View Slide

  17. Two seconds

    View Slide

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

  19. The average site kills conversions.

    View Slide

  20. Measure a starting point

    View Slide

  21. View Slide

  22. WebPageTest - webpagetest.org

    View Slide

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

  24. Timeline view

    View Slide

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

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

    much it’s costing

    View Slide

  27. What will get my visitors
    reading quickest?


    View Slide

  28. Doing it wrong

    View Slide

  29. JavaScript in the footer

    View Slide

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


    View Slide

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

    View Slide

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

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

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









  35. jQuery, doing_it_wrong()

    View Slide











  36. jQuery, doing_it_wrong()

    View Slide

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

    View Slide

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

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

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









  41. jQuery, the WordPress way

    View Slide









  42. jQuery, doing_it_wrong()

    View Slide










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

    View Slide

  44. Asynchronous JavaScript

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

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

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

  53. Browsers initiate requests
    The blocking nature of HTTP 1

    View Slide

  54. Blockers
    HTML

    View Slide

  55. Blockers
    HTML
    CSS

    View Slide

  56. Blockers
    HTML
    CSS

    View Slide

  57. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    FONTS

    View Slide

  58. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    FONTS

    View Slide

  59. Blockers
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View Slide

  60. Waterfall
    WebPageTest - webpagetest.org

    View Slide

  61. Waterfall
    WebPageTest - webpagetest.org

    View Slide

  62. Waterfall
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View Slide

  63. Waterfall
    HTML
    CSS
    IMG
    IMG
    IMG
    JS
    IFRAME
    FONTS

    View Slide

  64. HTTP/2
    An aside

    View Slide

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

    View Slide

  66. These titles are
    considered harmful

    View Slide

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

    View Slide

  68. caniuse.com/http2, March 2016

    View Slide

  69. caniuse.com/http2, March 2016

    View Slide

  70. Critical Path CSS

    View Slide

  71. w3.org/TR/preload/

    View Slide

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

    View Slide

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

    View Slide



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

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

    View Slide

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

    View Slide

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

    View Slide

  78. Preloading CSS

    View Slide

  79. Preloading CSS

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide



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

  88. View Slide

  89. pwcc.cc/wceu/loadcss

    View Slide

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

    View Slide

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



    HTML: uncached HTTP/1

    View Slide

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

    View Slide

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



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


  95. Cached Stylesheet

    View Slide


















  96. View Slide

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

    View Slide

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

    View Slide

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

    View Slide