Slowing Down To Go Faster: Responsive Web Design And The Problem Of Agility vs Robustness

2b3837af1d68d0b71639e693c780386f?s=47 Tom Maslen
November 15, 2013

Slowing Down To Go Faster: Responsive Web Design And The Problem Of Agility vs Robustness

The great irony of modern web development is that to make a website as fast as possible requires much more of your time. In an environment where you have to develop swiftly, how do you balance the need of meeting deadlines with the need to get the job done right? Tom Maslen from BBC News will take you through a number of techniques to help you to stay true to the idealisms of web development while also helping you to comprehend and master the increasing complexities of web browser support.

2b3837af1d68d0b71639e693c780386f?s=128

Tom Maslen

November 15, 2013
Tweet

Transcript

  1. SLOWING DOWN TO GO FASTER RESPONSIVE WEB DESIGN & THE

    PROBLEM OF AGILITY vs ROBUSTNESS
  2. Ciao! AT COPACABANA BEACH, BRAZIL 3 MILLION PEOPLE LISTENING TO

    THE POPE
  3. PEOPLE NEVER SAW IT THIS IS THE FIRST WEBSITE I

    EVER MADE, 3 MILLION
  4. Ciao! Hello! AN AUDIENCE OF 3 MILLION MAKING WEBPAGES IS

    CLOSEST I’LL EVER GET TO
  5. UBIQUITY LESS IMPORTANT THAN ACCESSIBILITY PERFORMANCE USABILITY SEO FRIENDLY NO

    JAVASCRIPT SEMANTICS LESS IMPORTANT THAN HTML CSS JAVASCRIPT OUR WEBSITES WE WANT AS MANY PEOPLE AS POSSIBLE TO VIEW
  6. PART 1 WHAT IS RESPONSIVE WEB DESIGN? Its when you

    resize the browser and the content changes width, right? YES
  7. But isn’t it also about building for mobiles first? YES

  8. And isn’t there a massive difference in device capabilities too?

    YES
  9. Can’t everyone just use an iPhone 5S? You’re not working

    hard enough if you can’t afford one NO!
  10. RESPONSIVE WEB DESIGN IS: A SOLUTION TO THE PROBLEM OF

    THE MASSIVE DIFFERENCES WE’RE NOW SEEING IN THE CLIENT
  11. ROBUSTNESS vs. AGILITY THE PROBLEM IS

  12. I WORK IN BBC NEWS VISUAL JOURNALISM...

  13. WE BUILD INFOGRAPHICS AND DATA VISUALISATIONS

  14. MORE DESIGN TIME RESPONSIVE WEB DESIGN TAKES LONGER MORE COMPLEX

    DEVELOPMENT MORE TESTING EVERYTHING WE MAKE IS NOW RESPONSIVE AND TAKES 3 TIMES LONGER TO BUILD
  15. PART 2 OBVIOUS ADVICE PERFORMANCE IS EASY, HERE ARE 4

    OBVIOUS TIPS TO HELP YOU...
  16. Small file sizes? Oh... My... God... #headfuck MAKE YOUR FILES

    SMALLER WORK EXPERIENCE MONKEY OBVIOUS RULE #1
  17. Less requests? Of course!!! #ideagasm MAKE LESS REQUESTS PROJECT MANAGER

    KITTEH OBVIOUS RULE #2
  18. Dag nammit you clever! #takemymoney ONLY DOWNLOAD WHAT YOU NEED

    ANYONE WHO LIKES PARALLAX SCROLLING OBVIOUS RULE #3
  19. Floored by your awesomeness #maslened DON’T BREAK WHAT YOU’VE ALREADY

    MADE THE GUY WHO BREAKS THE BUILD ALL THE TIME OBVIOUS RULE #4
  20. BUT... PUTTING IT INTO YOUR WORKFLOW WITH RESPONSIVE WEB DESIGN

    IS HARD
  21. BUILD YOUR WORKFLOW DOWNLOAD ONLY WHAT YOU NEED REDUCE DOWNLOADS

    IMPROVE TIME TO GLASS DON’T BREAK STUFF
  22. www.gruntjs.com

  23. www.gruntjs.com integralist.co.uk/Grunt-Boilerplate.html MARK McDONNELL @integralist

  24. IMPROVE TIME TO GLASS

  25. ANGRY GLASWEGIAN PINT GLASS Ay’m gonna deck ya! THIS IS

    NOT TIME TO GLASS
  26. THIS IS TIME TO GLASS ILYA GRIGORIK - @igrigorik PATRICK

    HAMANN - @patrickhamann http://bit.ly/16h5OHm http://bit.ly/18AOWOz “OPTIMIZING THE CRITICAL PATH” “CSS AND THE CRITICAL PATH”
  27. TIME TO GLASS

  28. WE DO THIS USING THIS TECHNIQUE

  29. CORE EXPERIENCE SIMPLE LAYOUT, FAST, ALL BROWSERS 7 8 BB

    OS5 (MANGO) 1.6 9 10 BB OS6+ (WEBKIT) 2.1+
  30. JAVASCRIPT IF BROWSER “CUTS THE MUSTARD”... if ( 'querySelector' in

    document && 'localStorage' in window && 'addEventListener' in window ) { // load JS application
  31. ENHANCED EXPERIENCE COMPLEX LAYOUT, FUNCTIONAL, MODERN BROWSERS CORE EXPERIENCE SIMPLE

    LAYOUT, FAST, ALL BROWSERS 7 8 BB OS5 (MANGO) 1.6 9 10 BB OS6+ (WEBKIT) 2.1+
  32. BUILD YOUR WORKFLOW CORE EXPERIENCE DOWNLOAD ONLY WHAT YOU NEED

    REDUCE DOWNLOADS IMPROVE TIME TO GLASS DON’T BREAK STUFF
  33. I’m gonna shoot you! STEVIE SOUDERS WILL GET ANGRY UNLESS...

  34. YOU ONLY DOWNLOAD WHAT YOU NEED

  35. Img$ 62%$ JS$ 17%$ Other$ 9%$ Flash$ 5%$ HTML$ 4%$

    CSS$ 3%$ httparchive.org/interesting.php AVERAGE % PER PAGE BY CONTENT TYPE LETS START WITH IMAGES
  36. WE CAN’T TELL BY DEVICE WIDTH WHAT SIZE IMAGE WE

    NEED
  37. SOMETIMES THEY ARE FULL WIDTH...

  38. OR HALF THE WIDTH...

  39. OR EVEN SMALLER

  40. WE NEED TO BUILD MULTIPLE VERSIONS OF THE SAME IMAGE...

  41. THEN DECIDE WHICH ONE TO USE ?

  42. IMAGER.JS IS A GRUNT TASK TO DO THIS

  43. MARK McDONNELL @integralist ADDY OSMANI @addyosmani MADE BY MYSELF AND

    THESE TWO CHAPS
  44. A GRUNTFILE ORIGINAL IMAGES YOU NEED...

  45. gruntfile.js responsive_images:  {        options:  {    

               sizes:  [{                        width:  320                },{                        width:  640                },{                        width:  1024                }]        },        files:  [{                cwd:  './original_img/',                src:  ['*.{jpg,gif,png}'],                dest:  './resp_img/'        }] } WHERE THE ORIGINAL IMAGES ARE GRUNT NEEDS TO KNOW...
  46. gruntfile.js responsive_images:  {        options:  {    

               sizes:  [{                        width:  320                },{                        width:  640                },{                        width:  1024                }]        },        files:  [{                cwd:  './original_img/',                src:  ['*.{jpg,gif,png}'],                dest:  './resp_img/'        }] } WHAT SIZES OF IMAGES YOU WANT GRUNT NEEDS TO KNOW...
  47. gruntfile.js responsive_images:  {        options:  {    

               sizes:  [{                        width:  320                },{                        width:  640                },{                        width:  1024                }]        },        files:  [{                cwd:  './original_img/',                src:  ['*.{jpg,gif,png}'],                dest:  './resp_img/'        }] } WHERE IMAGES WILL BE OUTPUTTED GRUNT NEEDS TO KNOW...
  48. <script  src="imager.js"></script> <script>    var  imager  =  new  Imager({  

         availableWidths:  [320,  640,  1024]    }); </script> IN YOUR HTML INCLUDE THE IMAGE.JS FILE AND INSTANTIATE AN OBJECT LIKE SO MUST BE SAME ARRAY FROM TWO SLIDES PREVIOUS
  49. In  your  HTML... <div  class="delayed-­‐image-­‐load"   data-­‐src="img/320/squirrel.jpg"></div> <img  class="image-­‐replace"  

    src="img/640/squirrel.jpg"  /> IS REPLACED BY USE THIS DIV INSTEAD OF A NORMAL IMG TAG IT WILL TURN INTO AN IMG TAG, AUTOMATICALLY CHOOSING THE BEST FITTING IMAGE
  50. grunt  responsive_images THE DIFFERENT WIDTH VERSIONS OF THE IMAGE RUNNING

    THIS COMMAND WILL GENERATE BEFORE AFTER
  51. BUILD YOUR WORKFLOW CORE EXPERIENCE DOWNLOAD ONLY WHAT YOU NEED

    REDUCE DOWNLOADS IMPROVE TIME TO GLASS DON’T BREAK STUFF AUTOMATED RESPONSIVE IMAGES
  52. REDUCE DOWNLOADS

  53. httparchive.org/interesting.php CACHE LIFETIME (DAYS) 56%$ 13%$ 18%$ 9%$ 4%$ 0%$

    10%$ 20%$ 30%$ 40%$ 50%$ 60%$ 70%$ 80%$ 90%$ 100%$ t$=$0$ 0$<$t$<=1$ 1$<$t$<=$30$ 30$<$t$<=$365$ t$>$365$
  54. PRO TIP CACHE JS, CSS & IMAGES FOR A YEAR

  55. github.com/h5bp/mobile-­‐boilerplate/.htaccess <IfModule  mod_expires.c> #  CSS  and  JavaScript ExpiresByType  application/javascript  "access

     plus  1  year" ExpiresByType  text/css                              "access  plus  1  year" </IfModule> SETTING THE CACHE
  56.                    

       </div>                </div>                <script  src="main.js?v=0.1.0"></script>        </body> </html> CHANGE THE PATH TO BREAK THE CACHE WHEN A VERSION OF THE FILE IS AVAILABLE
  57. THIS ISN’T EASY IF THERE ARE MANY FILES    

       <link  href="index.css?v=0.1.0"  />        <link  href="share.css?v=0.1.0"  />        </head> ...                        </div>                </div>        <script  src="index.js?v=0.1.0">            </script>        <script  src="nav.js?v=0.1.0">            </script>        <script  src="imager.js?v=0.1.0">            </script>        <script  src="share.js?v=0.1.0">            </script>        </body> </html> LUCKILY GRUNT CAN HELP US
  58. None
  59. JARROD OVERSON @jsoverson

  60. YOU NEED A PACKAGE FILE

  61. {    "name":  "Example",    "description":  "Example  app  for  Velocity

     EU  2013",    "version":  "0.1.1",    "devDependencies":  {        "grunt":                        "~0.4.1",        "grunt-­‐preprocess":  "~3.0.1"    } } APP VERSION package.json
  62. module.exports  =  function(grunt)  {    grunt.initConfig({        pkg:

     '<json:package.json>',        preprocess:  {            options:  {                context:  {                  version:  '<%=  pkg.version  %>'                }            },            multifile  :  {                files  :  {                        'example.html.tmpl'  :  'example.html'                }            }        }      });    grunt.loadNpmTasks('grunt-­‐preprocess'); }; REFERENCE GRUNT-PREPROCESS INSTRUCTIONS TEMPLATE OUTPUT Gruntfile.js TEMPLATE VARIABLE
  63.        <link  href="index.css?v=<!-­‐-­‐  @echo  version  -­‐-­‐>"  />  

         <link  href="share.css?v=<!-­‐-­‐  @echo  version  -­‐-­‐>”  />    </head> ...                        </div>                </div>        <script  src="index.js?v=<!-­‐-­‐  @echo  version  -­‐-­‐>">            </script>        <script  src="nav.js?v=<!-­‐-­‐  @echo  version  -­‐-­‐>">            </script>        <script  src="imager.js?v=<!-­‐-­‐  @echo  version  -­‐-­‐>">            </script>        <script  src="share.js?v=<!-­‐-­‐  @echo  version  -­‐-­‐>">            </script>    </body> </html> example.html.tmpl
  64.        <link  href="index.css?v=0.1.1"  />        <link

     href="share.css?v=0.1.1"  />    </head> ...                        </div>                </div>        <script  src="index.js?v=0.1.1">            </script>        <script  src="nav.js?v=0.1.1">            </script>        <script  src="imager.js?v=0.1.1">            </script>        <script  src="share.js?v=0.1.1">            </script>    </body> </html> example.html PACKAGE FILE OURSELVES BEFORE EACH RELEASE THIS IS NICE, BUT WE HAVE TO UPDATE THE
  65. None
  66. File  updated Path:  package.json Old  version:  0.1.0.  New  version:  0.1.1.

    Done,  without  errors. Waiting... OK >>  File  "main.js"  changed. Running  "version:build"  (version)  task LOOK
  67. Waiting... OK >>  File  "main.js"  changed. Running  "version:build"  (version)  task

    File  updated Path:  package.json Old  version:  0.1.1.  New  version:  0.1.1-­‐1. Done,  without  errors. LOOK
  68.        <link  href="index.css?v=0.1.1"  />        <link

     href="share.css?v=0.1.1"  />    </head> ...                        </div>                </div>        <script  src="index.js?v=0.1.1">            </script>        <script  src="nav.js?v=0.1.1">            </script>        <script  src="imager.js?v=0.1.1">            </script>        <script  src="share.js?v=0.1.1">            </script>    </body> </html> example.html AUTOMATED CACHE BREAKING!
  69. BUT... PROXY SERVERS DO NOT CACHE ASSETS WITH QUERY STRINGS

  70. BREAK THE CACHE BY A CHANGE IN THE FILE PATH,

    NOT THE QUERYSTRING PRO TIP <script  src="main.js?v=0.1.0"></script>  BAD  :-­‐( <script  src="main-­‐0.1.0.js"></script>      GOOD  :-­‐)
  71.        <link  href="index-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.css"  />  

         <link  href="share-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.css”  />    </head> ...                        </div>                </div>        <script  src="index-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.js">            </script>        <script  src="nav-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.js">            </script>        <script  src="imager-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.js">            </script>        <script  src="share-­‐<!-­‐-­‐  @echo  version  -­‐-­‐>.js">            </script>    </body> </html> example.html.tmpl MOVE THE VERSION NUMBER INTO THE FILE NAME
  72. #Rules  for  Versioned  Static  Files RewriteRule  ^(scripts|css)/(.+)-­‐(.+)\. (js|css)$  $1/$2.$4  [L]

    THIS REWRITE RULE... DOES THIS REDIRECTION... scripts/main-­‐0.1.0.js scripts/main.js
  73. BUILD YOUR WORKFLOW CORE EXPERIENCE DOWNLOAD ONLY WHAT YOU NEED

    REDUCE DOWNLOADS VERSION ASSETS IMPROVE TIME TO GLASS DON’T BREAK STUFF AUTOMATED LONG CACHE AUTOMATED RESPONSIVE IMAGES
  74. DON’T BREAK STUFF

  75. A RESPONSIVE VISUAL REGRESSION TESTING TOOL

  76. @sthulb STEVEN THULBOURN @jcleveley JOHN CLEVELEY @dblooman DAVID BLOOMAN

  77. LIVE SITE TEST SITE DIFFERENCES

  78. LIVE SITE TEST SITE DIFFERENCES

  79. BUILD YOUR WORKFLOW CORE EXPERIENCE DOWNLOAD ONLY WHAT YOU NEED

    REDUCE DOWNLOADS VERSION ASSETS IMPROVE TIME TO GLASS DON’T BREAK STUFF AUTOMATED REGRESSION TESTS AUTOMATED LONG CACHE AUTOMATED RESPONSIVE IMAGES
  80. ROBUSTNESS vs. AGILITY THE PROBLEM IS

  81. 5 INCHES 7 INCHES THE PROBLEM WILL ONLY INCREASE IN

    COMPLEXITY
  82. LAPTOP OR TABLET? THE PROBLEM WILL ONLY INCREASE IN COMPLEXITY

  83. TOTAL DIVERGENCE THE PROBLEM WILL ONLY INCREASE IN COMPLEXITY

  84. MULTIPLE INTERACTION TYPES PER DEVICE THE PROBLEM WILL ONLY INCREASE

    IN COMPLEXITY
  85. TOOLING & AUTOMATION THE SOLUTION IS

  86. THE END MOVE SWIFTLY TOM MASLEN, BBC NEWS @tmaslen