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. 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
  2. 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
  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/wceu/blocking 0.5s 1.0s 1.5s 2.0s 0% 0% 0% 100% 0% 86% 100% Blocked Unblocked
  7. All visitors have JavaScript disabled while it downloads. – Every

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

    dependancies '20160624-26', // version true // load in footer ); JavaScript, the WordPress way
  9. 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
  10. 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
  11. 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
  12. <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()
  13. 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()
  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' ); 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()
  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. <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()
  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> </html> jQuery, doing_it_wrong() pwcc.cc/wceu/jqueryfooter
  18. function pwcc_async_js( $tag, $handle ) { switch ( $handle )

    { case 'pwcc-scripts' : $tag = str_replace( '></script', ' async></script', $tag ); } return $tag; } Asynchronous JavaScript
  19. 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
  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. 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
  22. 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
  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 pwcc.cc/wceu/asyncjs
  24. Everything you know about performance is now wrong and former

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

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

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

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

    // dependencies "1.2.0", // version true // load in footer );
  29. <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
  30. if ( ! is_cached( 'pwcc-style' ) && ! is_http2() )

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

    { print_style_inline( 'pwcc-style' ); wp_enqueue_script( 'pwcc-load-css' ); } Inline CSS pwcc.cc/wceu/rapidcss
  32. <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'>
  33. Everything you know about performance is now wrong and former

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