$30 off During Our Annual Pro Sale. View Details »

Before the @mq

Before the @mq

Three case studies focusing on images and how to improve performance and download size. Provides examples of both client-side and server-side solutions.

Video available at http://weedygarden.net/2013/07/bdconf-2013/

Erik Runyon

July 22, 2013
Tweet

More Decks by Erik Runyon

Other Decks in Technology

Transcript

  1. What We’ll Cover I. Why We Optimize II. Articles BBC

    News III. Carousels WVU IV. In Depth Notre Dame
  2. 2010 2.6% 3.6% 7.2% 2011 4.4% 8.8% 26.1% 2012 13.3%

    17.7% 44.9% ND.edu Admissions Game Day Mobile Traffic
  3. http://www.websiteoptimization.com/speed/tweak/average-web-page/ http://www.webperformancetoday.com/2012/05/24/average-web-page-size-1-mb/ “The size of the average web page of

    the top 1000 websites has more than tripled since 2008. In the past five years from 2008 to late 2012 the average web page grew from 312K to 1114K, over 3.5 times larger” – websiteoptimization.com (Nov 11, 2012) “In the past 18 months, the average web page has grown by 50% — from 702 KB in November 2010 to 1042 KB on May 1, 2012. At this rate, the average page will hit 2MB by 2015.” – webperformancetoday.com (May 24, 2012)
  4. Sites used to generate these stats: http://bit.ly/highered-rwd averages for #highered

    RWD sites 128 sites sampled at full size requests size 61 1.7 MB
  5. Sites used to generate these stats: http://bit.ly/highered-rwd averages for #highered

    RWD sites 128 sites sampled with iPhone UA and narrow screen (to simulate mobile) requests size 57 1.6 MB
  6. 1-1.9 MB = 50 Sites used to generate these stats:

    http://bit.ly/highered-rwd averages for #highered RWD sites 128 sites sampled with iPhone UA and narrow screen (to simulate mobile) 2-2.9 MB = 15 3-3.9 MB = 11 > 4 MB = 6
  7. js css images Sites used to generate these stats: http://bit.ly/highered-rwd

    averages for #highered RWD sites 128 sites sampled with iPhone UA and narrow screen (to simulate mobile) 12 files / 227 KB 7 files / 99 KB 32 files / 1 MB 73% of page size
  8. …build a BBC News website that fits the needs of

    the maximum of users 3 years in the future. At the moment we have a mobile only responsive website. But eventually it will take over the desktop site. @tmaslen
  9. requests size css js images www.bbc.co.uk/news Launched 1997 m.bbc.co.uk/news Launched

    2012 196 1.4 MB 10 files / 64.4 KB 71 files / 419 KB 114 files / 823 KB DESKTOP requests size css js images 8 34 KB 3 files / 16.4 KB — 4 files / 4.9 KB BASIC only one content image requests size css js images 59 224 KB 5 files / 37.6 KB 8 files / 70.2 KB 41 files / 84.1 KB SMARTPHONE
  10. HTML5 browsers IE9+ Firefox 3.5+ Opera 9+ and probably further

    back Safari 4+ Chrome 1+ (I think) iPhone and iPad iOS1+ Android phone and tablets 2.1+ Blackberry OS6+ Windows 7.5+ new Mango version Mobile Firefox all the versions we tested Opera Mobile all the versions we tested HTML4 browsers IE8- Blackberry OS5- Nokia S60 v6- Nokia S40 all versions All other Symbian variants Windows 7 phone pre-Mango …and many more that are too numerous to mention. http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
  11. if('querySelector' in document && 'localStorage' in window && 'addEventListener' in

    window) { // bootstrap the application } “Cutting the Mustard” http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
  12. A large part of any JS library is its DOM

    selector. If the browser has native CSS selecting then it removes the need for a DOM selector. QuerySelector has been available in Firefox since 3.5 at least and has been working in webkit for ages. It also works in IE9. document.querySelector http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
  13. Although we are not using it yet, we are planning

    on making considerable use of it. Imagine that if you first came to the mobile site we downloaded all the stories straight away and stored them in localStorage. They’d then be available to use while you are going through an areas of sketchy bandwidth. window.localStorage http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
  14. Another large part of any JS library is event support.

    Every browser made in the last 6 years (except IE8) supports DOM level 2 events. If the browser supports this then we know it has better standards support than IE8. window.addEventListener http://responsivenews.co.uk/post/18948466399/cutting-the-mustard
  15. <!-- Original Article --> <div class="unit unit--regular unit--has-media"> <div class="unit__media">

    <div class="delayed-image-load" data-src="http://ichef.bbci.co.uk/news/200/media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" data- width="640" data-height="360"></div> </div> <div class="unit__body"> <div class="unit__header"> <h3 class="unit__title"> ! ! ! <a href="/news/world-europe-23000319" class="unit__link-wrapper"><span class="cta">Germany-Turkey diplomatic row erupts</span></a> ! ! ! </h3> <div class="unit__meta"> <div class="date" data-seconds="1371819374" data-datetime="21 June 2013"> 21 June 2013 </div> </div> </div> <div class="unit__summary"> <p class="summary">Germany summons the Turkish ambassador in a row over Turkey's bid for membership of the European Union.</p> </div> </div> </div> <!-- Enhanced Article --> <div class="unit unit--regular unit--has-media"> <a href="/news/world-europe-23000319" class="unit__link-wrapper"> <div class="unit__media"> <img src="http://ichef.bbci.co.uk/news/96/media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" datasrc="http://ichef.bbci.co.uk/news/200/ media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" class="image-replace" alt="" width="640" height="360"> </div> <div class="unit__body"> <div class="unit__header"> <h3 class="unit__title"><span class="cta"> Germany-Turkey diplomatic row erupts </span> </h3> <div class="unit__meta"> <div class="date relative-time" data-seconds="1371819374" data-datetime="21 June 2013" data-timestamp-inserted="true"> 2 hours ago </div> </div> </div> <div class="unit__summary"> <p class="summary">Germany summons the Turkish ambassador in a row over Turkey's bid for membership of the European Union.</p> </div> </div> </a> </div>
  16. <!-- Original Article --> <div class="unit unit--regular unit--has-media"> <div class="unit__media">

    <div class="delayed-image-load" data-src="http://ichef.bbci.co.uk/news/200/media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" data- width="640" data-height="360"></div> </div> <div class="unit__body"> <div class="unit__header"> <h3 class="unit__title"> ! ! ! <a href="/news/world-europe-23000319" class="unit__link-wrapper"><span class="cta">Germany-Turkey diplomatic row erupts</span></a> ! ! ! </h3> <div class="unit__meta"> <div class="date" data-seconds="1371819374" data-datetime="21 June 2013"> 21 June 2013 </div> </div> </div> <div class="unit__summary"> <p class="summary">Germany summons the Turkish ambassador in a row over Turkey's bid for membership of the European Union.</p> </div> </div> </div> <!-- Enhanced Article --> <div class="unit unit--regular unit--has-media"> <a href="/news/world-europe-23000319" class="unit__link-wrapper"> <div class="unit__media"> <img src="http://ichef.bbci.co.uk/news/96/media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" datasrc="http://ichef.bbci.co.uk/news/200/ media/images/68302000/jpg/_68302997_gerturkmerkelafp.jpg" class="image-replace" alt="" width="640" height="360"> </div> <div class="unit__body"> <div class="unit__header"> <h3 class="unit__title"><span class="cta"> Germany-Turkey diplomatic row erupts </span> </h3> <div class="unit__meta"> <div class="date relative-time" data-seconds="1371819374" data-datetime="21 June 2013" data-timestamp-inserted="true"> 2 hours ago </div> </div> </div> <div class="unit__summary"> <p class="summary">Germany summons the Turkish ambassador in a row over Turkey's bid for membership of the European Union.</p> </div> </div> </a> </div>
  17. <!-- Initial markup --> <div class="unit__media"> <div ! !! !

    class="delayed-image-load" ! !! ! data-src="http://path/to/image.jpg" ! !! ! data-width="640" data-height="360"> ! ! </div> </div> <!-- Post mustard cutting --> <div class="unit__media"> <img ! !! ! src="http://path/to/image.jpg" ! !! ! datasrc="http://original/path/to/image.jpg" ! !! ! class="image-replace" alt="" width="640" height="360"> </div>
  18. widths = [96, 130, 165, 200, 235, 270, 304, 340,

    375, 410, 445, 485, 520, 555, 590, 625, 660, 695, 736] http://responsivenews.co.uk/post/50092458307/images “We made an arbitary decision to add a breakpoint every 30px from 96px up to 736px… informed more by the image sizes that fit into the old grid system available in BBC’s GEL layout guide.”
  19. 96px 96px = 2 KB 200px = 5 KB 235px

    200px = 3 KB 235px = 4 KB 590px = 29 KB Viewport ~ 240px wide
  20. 96px 96px = 2 KB 200px = 5 KB 235px

    200px = 3 KB 235px = 4 KB 590px = 29 KB x27 Viewport ~ 240px wide
  21. “At the moment making the choice based on element size

    is the best fit for us, as element widths do not correlate to viewport widths. We use images in many different contexts, stretched across columns, left aligned, etc, so we have to use element width.” http://responsivenews.co.uk/post/50092458307/images
  22. The site records around 40 million unique users a week

    https://en.wikipedia.org/wiki/BBC_News_Online http://www.digitalspy.com/media/news/a437075/us-election-brings-bbc-news-website-traffic-high.html Coverage of the (2012 U.S.) election… brought 16.4 million unique browsers across the BBC website and mobile services on November 7.
  23. "…keeping the designer focused on achievable solutions at specific screen

    sizes by not trying to optimize one code base for everything and leveraging server-side solutions rather than force templating logic onto the front-end." @dmolsen
  24. http://xkcd.com/1174/ “If I click 'no', I've probably given up on

    everything, so don't bother taking me to the page I was trying to go to. Just drop me on the homepage. Thanks.”
  25. "The basic premise being that 90% of the mark-up and

    styles are the same on all browsers but some get just a little tweak here and there based on their browser's UA and supported properties. The primary images that we tweak are the carousel images. They're by far our biggest resource hog. By looking for mobile UAs we serve much smaller width/height imagery." @dmolsen
  26. CSS Mobile <link rel="stylesheet" href="base.css"> <link rel="stylesheet" href="flexslider.css" media="screen"> <link

    rel="stylesheet" href="layout.css"> <link rel="stylesheet" href="option-3.css"> <link rel="stylesheet" href="bootstrap.css"> <link rel="stylesheet" href="mobile-advanced.css"> Desktop <link rel="stylesheet" href="base.css"> <link rel="stylesheet" href="supersized.css" media="screen"> <link rel="stylesheet" href="supersized.shutter.css" media="screen"> <link rel="stylesheet" href="layout.css"> <link rel="stylesheet" href="option-3.css">
  27. CSS Mobile <link rel="stylesheet" href="base.css"> <link rel="stylesheet" href="flexslider.css" media="screen"> <link

    rel="stylesheet" href="layout.css"> <link rel="stylesheet" href="option-3.css"> <link rel="stylesheet" href="bootstrap.css"> <link rel="stylesheet" href="mobile-advanced.css"> Desktop <link rel="stylesheet" href="base.css"> <link rel="stylesheet" href="supersized.css" media="screen"> <link rel="stylesheet" href="supersized.shutter.css" media="screen"> <link rel="stylesheet" href="layout.css"> <link rel="stylesheet" href="option-3.css">
  28. JS Mobile <script src="jquery.flexslider-min.js"></script> <script src="modernizr.custom.js"></script> <script src="bootstrap.min.js"></script> <script src="navigation-option-6.js"></script>

    Desktop <script src="modernizr.custom.js"></script> <script src="jquery.easing.min.js"></script> <script src="supersized.3.2.6.js"></script> <script src="supersized.shutter.js"></script> <script src="navigation-option-6.js"></script>
  29. JS Mobile <script src="jquery.flexslider-min.js"></script> <script src="modernizr.custom.js"></script> <script src="bootstrap.min.js"></script> <script src="navigation-option-6.js"></script>

    Desktop <script src="modernizr.custom.js"></script> <script src="jquery.easing.min.js"></script> <script src="supersized.3.2.6.js"></script> <script src="supersized.shutter.js"></script> <script src="navigation-option-6.js"></script>
  30. Mobile <div class="flexslider"> <ul class="slides"> <li><img src="images/slideshow-mobile/69.jpg" alt="…" /><p class="flex-caption">…

    <a href='http://link'>Read More</a></p></li> <li><img src="images/slideshow-mobile/64.jpg" alt="…" /><p class="flex-caption">… <a href='http://link'>Read More</a></p></li> <li><img src="images/slideshow-mobile/71.jpg" alt="…" /><p class="flex-caption">… <a href='http://link'>Read More</a></p></li> <li><img src="images/slideshow-mobile/70.jpg" alt="…" /><p class="flex-caption">… <a href='http://link'>Read More</a></p></li> <li><img src="images/slideshow-mobile/54.jpg" alt="…" /><p class="flex-caption">… <a href='http://link'>Read More</a></p></li> </ul> </div> HTML
  31. Desktop <ul id="supersized"></ul> HTML <script type="text/javascript"> jQuery(function($){ $.supersized({ slide_interval :

    30000, transition : 1, transition_speed : 500, keyboard_nav : 0, slide_links : 'blank', slides : [ {image : 'images/slideshow/69.jpg', title : "…", thumb : 'images/slideshow/thumbs/69.jpg'}, {image : 'images/slideshow/64.jpg', title : "…", thumb : 'images/slideshow/thumbs/64.jpg'}, {image : 'images/slideshow/71.jpg', title : "…", thumb : 'images/slideshow/thumbs/71.jpg'}, {image : 'images/slideshow/70.jpg', title : "…", thumb : 'images/slideshow/thumbs/70.jpg'}, {image : 'images/slideshow/72.jpg', title : "…", thumb : 'images/slideshow/thumbs/72.jpg'} ] }); }); </script>
  32. Images <!-- Large Images--> <ul id="supersized" class="quality" style="visibility: visible;"> <li

    class="slide-0"><a><img src="images/slideshow/69.jpg"></a></li> <li class="slide-1"><a><img src="images/slideshow/64.jpg"></a></li> <li class="slide-2"><a><img src="images/slideshow/71.jpg"></a></li> <li class="slide-3"><a><img src="images/slideshow/70.jpg"></a></li> <li class="slide-4"><a><img src="images/slideshow/54.jpg"></a></li> </ul> HTML
  33. HTML Controls <!-- Navigation--> <div id="thumb-control"> <div id="prevthumb"></div> <div id="nextthumb"></div>

    <!--Control Bar--> <div id="controls-wrapper" class="load-item"> <div id="controls"> <!--Slide captions displayed here--> <div id="slidecaption"></div> <!--Arrow Navigation--> <a id="prevslide" class="load-item"></a> <a id="nextslide" class="load-item"></a> </div> </div> <div id="thumb-tray" class="load-item five-items"></div> </div>
  34. HTML Controls <!-- Navigation--> <div id="thumb-control"> <div id="prevthumb"></div> <div id="nextthumb"></div>

    <!--Control Bar--> <div id="controls-wrapper" class="load-item"> <div id="controls"> <!--Slide captions displayed here--> <div id="slidecaption">… <a href="http://link/to/story">Read More</a></div> <!--Arrow Navigation--> <a id="prevslide" class="load-item"></a> <a id="nextslide" class="load-item"></a> </div> </div> <div id="thumb-tray" class="load-item five-items"> <ul id="thumb-list"> <li class="thumb0"><img src="images/slideshow/thumbs/69.jpg"></li> <li class="thumb1"><img src="images/slideshow/thumbs/64.jpg"></li> <li class="thumb2"><img src="images/slideshow/thumbs/71.jpg"></li> <li class="thumb3"><img src="images/slideshow/thumbs/70.jpg"></li> <li class="thumb4"><img src="images/slideshow/thumbs/72.jpg"></li> </ul> </div> </div>
  35. HTML Controls <!-- Navigation--> <div id="thumb-control"> <div id="prevthumb"></div> <div id="nextthumb"></div>

    <!--Control Bar--> <div id="controls-wrapper" class="load-item"> <div id="controls"> <!--Slide captions displayed here--> <div id="slidecaption">… <a href="http://link/to/story">Read More</a></div> <!--Arrow Navigation--> <a id="prevslide" class="load-item"></a> <a id="nextslide" class="load-item"></a> </div> </div> <div id="thumb-tray" class="load-item five-items"> <ul id="thumb-list"> <li class="thumb0"><img src="images/slideshow/thumbs/69.jpg"></li> <li class="thumb1"><img src="images/slideshow/thumbs/64.jpg"></li> <li class="thumb2"><img src="images/slideshow/thumbs/71.jpg"></li> <li class="thumb3"><img src="images/slideshow/thumbs/70.jpg"></li> <li class="thumb4"><img src="images/slideshow/thumbs/72.jpg"></li> </ul> </div> </div>
  36. requests transferred css js images 25 400 KB 1 files

    / 21 KB 5 files / 63.4 KB 18 files / 309 KB requests transferred css js images 37 994 KB 1 files / 14 KB 5 files / 68 KB 30 files / 903 KB MOBILE DESKTOP
  37. “I wanted to share my opinion of the new ND

    web site with you - in a word, it's awful. Quite frankly, I am unable to find anything about the site that is positive. It is not clear why the change was made but the individual that came up with the idea should be fired along with the individual(s) that approved the change. Contrary to the old site - I make every effort to avoid using the new site.”
  38. Approach #1: 1x1 gif Doesn’t scale proportionally without javascript If

    width/height is set to “auto” in CSS, reverts to 1x1 http://codepen.io/erunyon/pen/uqypx http://www.456bereastreet.com/archive/201306/how_to_proportionally_scale_images_that_have_dimension_attributes/
  39. Our Solution Replace as many images as possible with solid

    PNG’s and load actual image when necessary.
  40. <img class="img-replace" src="data:image/png;base64,LongStringOfDataWithTheSameDimensionsAsTheImage" width="112" height="112" alt="Description of the image" title="Description

    of the image" data-image="/path/to/the/image.jpg" data-width="112" data-height="112"> <noscript> <img class="img-noscript" src="/path/to/the/image.jpg" width="112" height="112" alt="Description of the image" title="Description of the image"> </noscript>
  41. The Result 38 requests * 393 KB * (down from

    130 requests and 2.4 MB) * Varies by day and browser