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

WordCamp Ubud: Performance - Moving to HTTP2

WordCamp Ubud: Performance - Moving to HTTP2

Peter Wilson

April 23, 2017
Tweet

More Decks by Peter Wilson

Other Decks in Technology

Transcript

  1. Total page size (MB) Nov 2011 - April 2017 0.5

    1.0 1.5 2.0 2.5 3.0 1 Nov '11 1 Jul '12 1 Mar '13 1 Nov '13 1 Jul '14 1 Mar '15 1 Nov '15 1 Jul '16 1 Mar '17 httparchive.org/trends.php, April 2017
  2. Assets per page Nov 2011 - April 2017 20 40

    60 80 100 120 140 1 Nov '1115 May '121 Dec '1215 Jun '13 1 Jan '14 15 Jul '14 1 Feb '1515 Aug '151 Mar '1615 Sep '16 1 Apr '17 httparchive.org/trends.php, March 2017
  3. 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
  4. 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+
  5. 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
  6. Comparison timelines Additional blocking request in HTML Header Timed using

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

    1.5s 2.0s 0% 0% 0% 100% 0% 86% 100% Blocked Unblocked Timed using WebPageTest - pwcc.cc/wceu/blocking
  8. All visitors have JavaScript disabled while it downloads. – Every

    progressive enhancement advocate ever “ ”
  9. wp_enqueue_script( 'pwcc-scripts', // handle '/functions.js', // source null, // no

    dependancies '20160624-26', // version true // load in footer ); JavaScript, the WordPress way
  10. 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
  11. 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
  12. 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
  13. <html> <head> <script src='jquery.js'></script><!--32kB--> <script src='jquery-migrate.js'></script><!--4.4kB--> </head> <body> <!-- Site

    content. --> <script src='/functions.js'></script> </body> </html> jQuery, doing_it_wrong()
  14. 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()
  15. 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()
  16. 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()
  17. <html> <head> <!-- HTML Header. --> </head> <body> <!-- Site

    content. --> <script src='jquery.js'></script><!--32kB--> <script src='jquery-migrate.js'></script><!--4.4kB--> <script src='/functions.js'></script> </body> jQuery, doing_it_wrong()
  18. <html> <head> <!-- HTML Header. --> </head> <body> <!-- Site

    content. --> <script src='jquery.js'></script><!--32kB--> <script src='jquery-migrate.js'></script><!--4.4kB--> <script src='/functions.js'></script> </body> </html> jQuery, doing_it_wrong() pwcc.cc/go/jqueryfooter
  19. function pwcc_async_js( $tag, $handle ) { switch ( $handle )

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

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

    { case 'pwcc-scripts' : // Falls through case 'picturefill' : $tag = str_replace( '></script', ' async></script', $tag ); } return $tag; } Asynchronous JavaScript
  22. switch ( $handle ) { case 'pwcc-scripts' : // Falls

    through case 'picturefill' : $tag = str_replace( '></script', ' async></script', $tag ); } return $tag; } add_filter( 'script_loader_tag', 'pwcc_async_js', 10, 2 ); Asynchronous JavaScript
  23. 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
  24. 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
  25. Everything you know about performance is now wrong and former

    best practices are now an anti-pattern and considered harmful.
  26. CSS, the WordPress way wp_enqueue_style( 'pwcc-style', // handle get_stylesheet_uri(), //

    source array(), // no dependancies '20160624-26', // version 'all' // media );
  27. Server push if ( is_cached( 'pwcc-style' ) ) { pwcc_preload_style(

    'pwcc-style' ); } else /* file not cached */ { pwcc_preload_style( 'pwcc-style', false ); }
  28. is_cached() function is_cached( $handle, $version ) { if ( $version

    === $_COOKIE[ $handle ] ) { return true; } else { return false; } }
  29. Register loadCSS wp_register_script( 'pwcc-load-css', // handle '/loadcss.js', // file array(),

    // dependencies "1.2.0", // version true // load in footer );
  30. <style type='text/css'>/* Critical CSS */</style> <link rel='preload' href='/style.css' as='style' onload='this.rel="stylesheet"'>

    <noscript> <link rel='stylesheet' href='/style.css' /> </noscript> HTML: uncached HTTP/1
  31. if ( ! is_cached( 'pwcc-style' ) && ! is_http2() )

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

    { print_style_inline( 'pwcc-style' ); wp_enqueue_script( 'pwcc-load-css' ); } Inline CSS pwcc.cc/wceu/rapidcss
  33. <link rel='shortcut icon' href='/favicon.ico'> <link rel='apple-touch-icon' sizes='57x57' href='/….png'> <link rel='apple-touch-icon'

    sizes='114x114' href='/….png'> <link rel='apple-touch-icon' sizes='72x72' href='/….png'> <link rel='apple-touch-icon' sizes='144x144' href='/….png'> <link rel='apple-touch-icon' sizes='60x60' href='/….png'> <link rel='apple-touch-icon' sizes='120x120' href='/….png'> <link rel='apple-touch-icon' sizes='76x76' href='/….png'> <link rel='apple-touch-icon' sizes='152x152' href='/….png'> <link rel='icon' type='image/png' href='/….png'> <link rel='icon' type='image/png' href='/….png' sizes='160x160'> <link rel='icon' type='image/png' href='/….png' sizes='96x96'> <link rel='icon' type='image/png' href='/….png' sizes='16x16'> <link rel='icon' type='image/png' href='/….png' sizes='32x32'> <meta name='msapplication-TileColor' content='#006ef6'> <meta name='msapplication-TileImage' content='/….png'> <meta name='msapplication-config' content='/browserconfig.xml'>
  34. Everything you know about performance is now wrong and former

    best practices are now an anti-pattern and considered harmful.