Performance &
    Responsive Web Design
    (RWD)
    NebraskaJS via @zachleat

    November 8, 2013


Thursday, November 8, 12
About Me


    ✤    @zachleat on

    ✤    zachleat.com
         underscore_dot.dash@zachleat.com


    ✤    Zach Leatherman

    ✤




Thursday, November 8, 12
My Projects
    ✤    BigText           ✤   parseIntimate.com




Thursday, November 8, 12
My Projects
    ✤    ALARMd.com        ✤   f2em.com




Thursday, November 8, 12
Housekeeping



    ✤    We need one or more volunteers to speak at January’s NebraskaJS.

    ✤    Tweet @nebraskajs with Topic Ideas even if you don’t want to speak.




Thursday, November 8, 12
Goals

    ✤    Primer

    ✤    RWD !== Media Queries

    ✤    99 Problems

    ✤    Buzzkills

    ✤    RWD Showcase Showdown

    ✤    Be kind, RWD.


Thursday, November 8, 12
Primer




Thursday, November 8, 12
RWD is



    ✤    A Flexible Grid            (Fluid: % + Min Widths)


    ✤    Flexible Media (Images, Video)
    ✤
         (Not Just)        Media Queries


                                                        http://unstoppablerobotninja.com/entry/on-being-responsive

Thursday, November 8, 12
http://www.w3.org/History/19921103-hypertext/hypertext/WWW/TheProject.html
Thursday, November 8, 12
http://www.w3.org/History/19921103-hypertext/hypertext/WWW/TheProject.html
Thursday, November 8, 12
http://www.w3.org/History/19921103-hypertext/hypertext/WWW/TheProject.html
Thursday, November 8, 12
RWD & performance

    ✤    Two alternatives to RWD:

          ✤   Do nothing

          ✤   Use a separate m.dot site

               ✤    Redirects are slow.

               ✤    Maintenance of UA-Parsing Server
                    Side Redirects (WURFL updates ~monthly)

               ✤    Content Strategy    (Desktop Mode link)

                                                              http://en.m.wikipedia.org/?useformat=mobile#_


Thursday, November 8, 12
Google recommends RWD


    ✤    “It keeps your desktop and mobile content on a single URL, which
         is easier for your users to interact with, share, and link to and for
         Google’s algorithms to assign the indexing properties to your
         content.”

    ✤    “Google can discover your content more efficiently as we wouldn't
         need to crawl a page with the different Googlebot user agents to
         retrieve and index all the content.”


    http://googlewebmastercentral.blogspot.com/2012/06/recommendations-for-building-smartphone.html
Thursday, November 8, 12
Content Strategy


         “Mobile users want to see our menu,
         hours, and delivery number. Desktop
         users definitely want this 1mb png of
         someone smiling at a salad.”


    https://twitter.com/wilto/status/63284673723375616


Thursday, November 8, 12
Thursday, November 8, 12
99 Problems


    ✤    Browsers Download and Block Rendering on Unnecessary CSS

    ✤    Browsers Sometimes Download Unnecessary Images

    ✤    Big Images are Wasted on Small Screens

          ✤   Related: Retina Images are Wasted on <snob>Blurry</snob>
              Screens




Thursday, November 8, 12
The “Average” Web Page




                           http://httparchive.org/interesting.php#bytesperpage




Thursday, November 8, 12
JavaScript Can Block




    ✤    “With scripts, progressive rendering is blocked for all content
         below the script.”




    http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/


Thursday, November 8, 12
JavaScript that Doesn’t Block




         <script	
  src></script>
         </body>



    http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/


Thursday, November 8, 12
JavaScript that Doesn’t Block


         <head>
         <!-­‐-­‐	
  Downloads	
  right	
  away	
  -­‐-­‐>
         <script	
  src	
  async></script>
         <!-­‐-­‐	
  Waits	
  to	
  download	
  -­‐-­‐>
         <script	
  src	
  defer></script>


    http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/


Thursday, November 8, 12
JavaScript that Doesn’t Block


      var	
  script	
  =	
  document.createElement("script");
    script.type	
  =	
  "text/javascript";
    script.src	
  =	
  "foo.js";

    document.getElementsByTagName("head")
    [0].appendChild(script);


    http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/


Thursday, November 8, 12
Stylesheets Block

    ✤    “Browsers (except Opera) block rendering until all screen CSS
         arrives. With the worst possible experience: white page.”

    ✤    “Browsers download CSS they don't need, e.g. print, tv, device-
         ratio... And most browsers (except Opera and Webkit) block
         rendering because of these too”
    ✤    http://www.phpied.com/files/css-loading/mq.php?mq=all



    http://www.phpied.com/css-and-the-critical-path/


Thursday, November 8, 12
WebKit

      <!-­‐-­‐	
  blocking	
  stylesheet,	
  nothing	
  renders	
  until	
  it	
  is	
  
      downloaded	
  and	
  parsed	
  -­‐-­‐>	
  
    <link	
  href="main.css"	
  rel="stylesheet">

    <!-­‐-­‐	
  non-­‐blocking,	
  low	
  download	
  priority	
  because	
  of	
  the	
  
    evaluated	
  media	
  query	
  -­‐-­‐>
    <link	
  href="i-­‐want-­‐a-­‐monitor-­‐of-­‐this-­‐size.css"	
  
    rel="stylesheet"	
  media="(min-­‐width:	
  4000px)">

    <!-­‐-­‐	
  print	
  stylesheet	
  is	
  non-­‐blocking	
  -­‐-­‐>
    <link	
  href="noop.css"	
  rel="stylesheet"	
  media="print">


    http://www.igvita.com/2012/06/14/debunking-responsive-css-performance-myths/


Thursday, November 8, 12
Everything Else*


    <!-­‐-­‐	
  blocking	
  stylesheet,	
  nothing	
  renders	
  until	
  it	
  is	
  
    downloaded	
  and	
  parsed	
  (timeouts	
  may	
  vary)	
  -­‐-­‐>	
  
    <link	
  href="main.css"	
  rel="stylesheet">
    <link	
  href="i-­‐want-­‐a-­‐monitor-­‐of-­‐this-­‐size.css"	
  
    rel="stylesheet"	
  media="(min-­‐width:	
  4000px)">
    <link	
  href="noop.css"	
  rel="stylesheet"	
  media="print">




Thursday, November 8, 12
Downloading CSS




              http://scottjehl.github.com/CSS-Download-Tests/




Thursday, November 8, 12
Downloading CSS
    Firefox 16              Opera 12




    Safari 6               Chrome 22




Thursday, November 8, 12
Solutions


    ✤    CSS is sacred. Choose minimal when possible.

    ✤    Separate <link> elements for each Media Query

          ✤   Doesn’t scale if you have a lot of breakpoints.

          ✤   Good for WebKit, what about everything else?

    ✤    eCSSential



Thursday, November 8, 12
eCSSential


    ✤    “Making responsive CSS load the way it should.”
    ✤    Downloads Blocking CSS that matches media
         queries
    ✤    Downloads other CSS async, non-blocking
    ✤    https://github.com/filamentgroup/eCSSential




Thursday, November 8, 12
matchMedia

    if	
  (window.matchMedia("(min-­‐width:	
  400px)").matches)	
  {
    	
  	
  /*	
  the	
  view	
  port	
  is	
  at	
  least	
  400	
  pixels	
  wide	
  */
    }	
  else	
  {
    	
  	
  /*	
  the	
  view	
  port	
  is	
  less	
  than	
  400	
  pixels	
  wide	
  */
    }




    https://developer.mozilla.org/en-US/docs/DOM/window.matchMedia

Thursday, November 8, 12
matchMedia




                http://caniuse.com/#feat=matchmedia




                   Polyfill: https://github.com/paulirish/matchMedia.js/
                 Careful with IE8-, the polyfill requires Media Query support




Thursday, November 8, 12
eCSSential

              <head>
    	
  	
  	
  	
  <script>
    	
  	
  	
  	
  <!-­‐-­‐	
  Inline	
  eCSSential.min.js	
  -­‐-­‐>

    	
  	
  	
  	
  eCSSential({
    	
  	
  	
  	
  	
  	
  	
  	
  "all":	
  "css/all.css",
    	
  	
  	
  	
  	
  	
  	
  	
  "(min-­‐width:	
  20em)":	
  "css/min-­‐20em.css",
    	
  	
  	
  	
  	
  	
  	
  	
  "(min-­‐width:	
  37.5em)":	
  "css/min-­‐37.5em.css",
    	
  	
  	
  	
  	
  	
  	
  	
  "(min-­‐width:	
  50em)":	
  "css/min-­‐50em.css",
    	
  	
  	
  	
  	
  	
  	
  	
  "(min-­‐width:	
  62.5em)":	
  "css/min-­‐62.5em.css"
    	
  	
  	
  	
  });
    	
  	
  	
  	
  </script>
    </head>




Thursday, November 8, 12
eCSSential Demo




    ✤    http://filamentgroup.github.com/eCSSential/examples/concat/




Thursday, November 8, 12
Images Don’t Block

    ✤    Doesn’t mean they get a free pass.




Thursday, November 8, 12
Images Don’t Block

    ✤    Doesn’t mean they get a free pass.




                  7 5 3 KB
Thursday, November 8, 12
Downloading Images (CSS)


    <div	
  id="test1">
    	
  	
  	
  	
  <img	
  src="images/test1.png"	
  alt=""	
  />
    </div>
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test1	
  {	
  display:none;	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)




                        PE
    <div	
  id="test1">




                      O
    	
  	
  	
  	
  <img	
  src="images/test1.png"	
  alt=""	
  />




                    N
    </div>
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test1	
  {	
  display:none;	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)


    <div	
  id="test2"></div>
    #test2	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test2.png');
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test2	
  {display:none;}
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)




                        PE
    <div	
  id="test2"></div>




                      O
    #test2	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test2.png');




                    N
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test2	
  {display:none;}
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)

    <div	
  id="test3">
    	
  	
  	
  	
  <div></div>
    </div>
    #test3	
  div	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test3.png');
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test3	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  display:none;
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)

    <div	
  id="test3">
    	
  	
  	
  	
  <div></div>




                                   K
    </div>
    #test3	
  div	
  {




                                 O
    	
  	
  	
  	
  background-­‐image:url('images/test3.png');
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test3	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  display:none;
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)

    <div	
  id="test4"></div>
    #test4	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test4-­‐desktop.png');
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test4	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  background-­‐image:url('images/test4-­‐mobile.png');
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)

    <div	
  id="test4"></div>




                                     K
    #test4	
  {




                                   O
    	
  	
  	
  	
  background-­‐image:url('images/test4-­‐desktop.png');




                                 ~
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  all	
  and	
  (max-­‐width:	
  600px)	
  {
    	
  	
  	
  	
  #test4	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  background-­‐image:url('images/test4-­‐mobile.png');
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)
    <div	
  id="test7"></div>
    #test7	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test7-­‐lowres.png');
    	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  height:75px;
    }
    @media	
  only	
  screen	
  and	
  (-­‐webkit-­‐min-­‐device-­‐pixel-­‐ratio:	
  1.5),
    only	
  screen	
  and	
  (min-­‐-­‐moz-­‐device-­‐pixel-­‐ratio:	
  1.5),
    only	
  screen	
  and	
  (-­‐o-­‐min-­‐device-­‐pixel-­‐ratio:	
  3/2),
    only	
  screen	
  and	
  (min-­‐device-­‐pixel-­‐ratio:	
  1.5)	
  {
    	
  	
  	
  	
  #test7	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  background-­‐image:url('images/test7-­‐highres.png');
    	
  	
  	
  	
  	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  	
  	
  	
  	
  height:75px;
    	
  	
  	
  	
  	
  	
  	
  	
  /*	
  Editors	
  note:	
  this	
  should	
  use	
  background-­‐size	
  */
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)
    <div	
  id="test7"></div>
    #test7	
  {
    	
  	
  	
  	
  background-­‐image:url('images/test7-­‐lowres.png');
    	
  	
  	
  	
  width:200px;




                                                           K
    	
  	
  	
  	
  height:75px;
    }




                                                         O
    @media	
  only	
  screen	
  and	
  (-­‐webkit-­‐min-­‐device-­‐pixel-­‐ratio:	
  1.5),
    only	
  screen	
  and	
  (min-­‐-­‐moz-­‐device-­‐pixel-­‐ratio:	
  1.5),
    only	
  screen	
  and	
  (-­‐o-­‐min-­‐device-­‐pixel-­‐ratio:	
  3/2),
    only	
  screen	
  and	
  (min-­‐device-­‐pixel-­‐ratio:	
  1.5)	
  {
    	
  	
  	
  	
  #test7	
  {
    	
  	
  	
  	
  	
  	
  	
  	
  background-­‐image:url('images/test7-­‐highres.png');
    	
  	
  	
  	
  	
  	
  	
  	
  width:200px;
    	
  	
  	
  	
  	
  	
  	
  	
  height:75px;
    	
  	
  	
  	
  	
  	
  	
  	
  /*	
  Editors	
  note:	
  this	
  should	
  use	
  background-­‐size	
  */
    	
  	
  	
  	
  }
    }




    http://timkadlec.com/2012/04/media-query-asset-downloading-results/

Thursday, November 8, 12
Downloading Images (CSS)



    ✤    Coming to a browser near you: image-­‐set()

    ✤    http://blog.cloudfour.com/safari-6-and-chrome-21-add-image-set-to-
         support-retina-images/




Thursday, November 8, 12
Downloading <img>



    ✤    RESPONSIVE IMAGES
    ✤    Whatever solution you pick, make sure it doesn’t
         make duplicate requests.




Thursday, November 8, 12
Downloading <img>

    ✤    If possible, use Vectors (SVG) over Bitmaps
         (PNG). It’ll look great on HDPI screens.
    ✤    Vectors are a shortcut for Responsive Images.
    ✤    Note: Canvas content is bitmapped, but you can
         redraw at higher resolutions.
    ✤    Side Note: Font icons are a great scalable
         alternative to PNG icons
Thursday, November 8, 12
Picturefill



    ✤    “A Responsive Images approach that you can use today”

    ✤    https://github.com/scottjehl/picturefill




Thursday, November 8, 12
Picturefill

    <div	
  data-­‐picture	
  data-­‐alt="A	
  giant	
  stone	
  face	
  at	
  The	
  Bayon	
  temple	
  in	
  Angkor	
  Thom,	
  
    Cambodia">
    	
  	
  	
  	
  <div	
  data-­‐src="external/imgs/small.jpg"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="external/imgs/medium.jpg"	
  data-­‐media="(min-­‐width:	
  400px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="external/imgs/large.jpg"	
  data-­‐media="(min-­‐width:	
  800px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="external/imgs/extralarge.jpg"	
  data-­‐media="(min-­‐width:	
  
    1000px)"></div>

    	
  	
  	
  	
  <!-­‐-­‐	
  Fallback	
  content	
  for	
  non-­‐JS	
  browsers.	
  Same	
  img	
  src	
  as	
  the	
  initial,	
  
    unqualified	
  source	
  element.	
  -­‐-­‐>
    	
  	
  	
  	
  <noscript><img	
  src="external/imgs/small.jpg"	
  alt="A	
  giant	
  stone	
  face	
  at	
  The	
  
    Bayon	
  temple	
  in	
  Angkor	
  Thom,	
  Cambodia"></noscript>
    </div>




    http://scottjehl.github.com/picturefill/


Thursday, November 8, 12
Picturefill



    ✤    data-­‐media="(min-­‐width:	
  400px)"

    ✤    Uses	
  matchMedia.

    ✤    No	
  duplicate	
  requests!




Thursday, November 8, 12
Picturefill (HDPI)


    <div	
  data-­‐picture	
  data-­‐alt="A	
  giant	
  stone	
  face	
  at	
  The	
  Bayon	
  temple	
  in	
  Angkor	
  Thom,	
  
    Cambodia">
    	
  	
  	
  	
  <div	
  data-­‐src="small.jpg"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="small.jpg"	
  	
  	
  	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐device-­‐pixel-­‐ratio:	
  2.0)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="medium.jpg"	
  	
  	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  400px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="medium_x2.jpg"	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  400px)	
  and	
  (min-­‐device-­‐pixel-­‐ratio:	
  2.0)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="large.jpg"	
  	
  	
  	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  800px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="large_x2.jpg"	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  800px)	
  and	
  (min-­‐device-­‐pixel-­‐ratio:	
  2.0)"></div>	
  	
  
    	
  	
  	
  	
  <div	
  data-­‐src="extralarge.jpg"	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  1000px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="extralarge_x2.jpg"	
  data-­‐media="(min-­‐width:	
  1000px)	
  and	
  (min-­‐device-­‐pixel-­‐ratio:	
  2.0)"></div>	
  

    	
  	
  	
  	
  ...
    </div>




    http://scottjehl.github.com/picturefill/


Thursday, November 8, 12
Compressive Images
          ✤   Pump up the size, pump up the JPEG compression

          ✤   Scale down in the browser

          ✤   http://filamentgroup.com/lab/rwd_img_compression/




Thursday, November 8, 12
Picturefill Simplifes to (HDPI)


    <div	
  data-­‐picture	
  data-­‐alt="A	
  giant	
  stone	
  face	
  at	
  The	
  Bayon	
  temple	
  in	
  Angkor	
  Thom,	
  
    Cambodia">
    	
  	
  	
  	
  <div	
  data-­‐src="small_compressive.jpg"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="medium_compressive.jpg"	
  	
  	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  400px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="large_compressive.jpg"	
  	
  	
  	
  	
  	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  800px)"></div>
    	
  	
  	
  	
  <div	
  data-­‐src="extralarge_compressive.jpg"	
  	
  	
  	
  data-­‐media="(min-­‐width:	
  1000px)"></div>

    	
  	
  	
  	
  <!-­‐-­‐	
  TODO:	
  adjust	
  rendered	
  sizes	
  -­‐-­‐>
    	
  	
  	
  	
  ...
    </div>



         ✤      Careful with Memory Consumption!


Thursday, November 8, 12
Buzzkills




Thursday, November 8, 12
Buzzkill #1: Advertising



    ✤    Pit of despair: full of document.write, iframes, blocking JavaScript
         (errors galore) and general badness.

    ✤    Inject advertising iframes using JavaScript (after onload)

          ✤   document.createElement(‘iframe’);




Thursday, November 8, 12
Buzzkill #2: Social Networking
    Widgets
                     Network         Requests   Size (After GZIP)
                                                 Compare to jQuery 1.8.2: 32KB



                    ShareThis          19               98.9KB

                     Facebook           3               41.2KB

                           Twitter      5                 48KB

                      Google+           8               30.8KB

Thursday, November 8, 12
SocialCount



    ✤    4 KB CSS, 7KB JavaScript (unminified,     ✤   Initializes Native Widgets on Hover / Tap
         ungzipped)                                   for Inline +1 / Like and Tweet.

    ✤    2 requests, optional +1 for Counts       ✤   In use on f2em.com

    ✤    Non-Blocking

    ✤    Sharing still works without JavaScript



Thursday, November 8, 12
SocialCount


                                                  ng So on
                           C om i
    ✤    4 KB CSS, 7KB JavaScript (unminified,      ✤   Initializes Native Widgets on Hover / Tap
         ungzipped)                                    for Inline +1 / Like and Tweet.

    ✤    2 requests, optional +1 for Counts        ✤   In use on f2em.com

    ✤    Non-Blocking

    ✤    Sharing still works without JavaScript



Thursday, November 8, 12
Showcase Showdown




Thursday, November 8, 12
Boston Globe




                                          1.31 MB
               Advertising, Video Player, Web Fonts, Tracking and Analytics



Thursday, November 8, 12
Disney.com




                                             1.59 MB
                           Advertising, Web Fonts, Tracking and Analytics



Thursday, November 8, 12
Starbucks




Thursday, November 8, 12
Time.com




Thursday, November 8, 12
Smashing Magazine




                                             1.87 MB
                           Advertising, Web Fonts, Tracking and Analytics



Thursday, November 8, 12
RWD & Performance


    ✤    “The fastest web site is the one with nothing on it.”

    ✤    We’re in the problem solving business.

          ✤   Solutions often require Code.

               ✤    jQuery and Cross Browser DOM API Compatibility

    ✤    Solve more problems than you create.



Thursday, November 8, 12

Performance & Responsive Web Design

  • 1.
    Performance & Responsive Web Design (RWD) NebraskaJS via @zachleat November 8, 2013 Thursday, November 8, 12
  • 2.
    About Me ✤ @zachleat on ✤ zachleat.com underscore_dot.dash@zachleat.com ✤ Zach Leatherman ✤ Thursday, November 8, 12
  • 3.
    My Projects ✤ BigText ✤ parseIntimate.com Thursday, November 8, 12
  • 4.
    My Projects ✤ ALARMd.com ✤ f2em.com Thursday, November 8, 12
  • 5.
    Housekeeping ✤ We need one or more volunteers to speak at January’s NebraskaJS. ✤ Tweet @nebraskajs with Topic Ideas even if you don’t want to speak. Thursday, November 8, 12
  • 6.
    Goals ✤ Primer ✤ RWD !== Media Queries ✤ 99 Problems ✤ Buzzkills ✤ RWD Showcase Showdown ✤ Be kind, RWD. Thursday, November 8, 12
  • 7.
  • 8.
    RWD is ✤ A Flexible Grid (Fluid: % + Min Widths) ✤ Flexible Media (Images, Video) ✤ (Not Just) Media Queries http://unstoppablerobotninja.com/entry/on-being-responsive Thursday, November 8, 12
  • 9.
  • 10.
  • 11.
  • 12.
    RWD & performance ✤ Two alternatives to RWD: ✤ Do nothing ✤ Use a separate m.dot site ✤ Redirects are slow. ✤ Maintenance of UA-Parsing Server Side Redirects (WURFL updates ~monthly) ✤ Content Strategy (Desktop Mode link) http://en.m.wikipedia.org/?useformat=mobile#_ Thursday, November 8, 12
  • 13.
    Google recommends RWD ✤ “It keeps your desktop and mobile content on a single URL, which is easier for your users to interact with, share, and link to and for Google’s algorithms to assign the indexing properties to your content.” ✤ “Google can discover your content more efficiently as we wouldn't need to crawl a page with the different Googlebot user agents to retrieve and index all the content.” http://googlewebmastercentral.blogspot.com/2012/06/recommendations-for-building-smartphone.html Thursday, November 8, 12
  • 14.
    Content Strategy “Mobile users want to see our menu, hours, and delivery number. Desktop users definitely want this 1mb png of someone smiling at a salad.” https://twitter.com/wilto/status/63284673723375616 Thursday, November 8, 12
  • 15.
  • 16.
    99 Problems ✤ Browsers Download and Block Rendering on Unnecessary CSS ✤ Browsers Sometimes Download Unnecessary Images ✤ Big Images are Wasted on Small Screens ✤ Related: Retina Images are Wasted on <snob>Blurry</snob> Screens Thursday, November 8, 12
  • 17.
    The “Average” WebPage http://httparchive.org/interesting.php#bytesperpage Thursday, November 8, 12
  • 18.
    JavaScript Can Block ✤ “With scripts, progressive rendering is blocked for all content below the script.” http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/ Thursday, November 8, 12
  • 19.
    JavaScript that Doesn’tBlock <script  src></script> </body> http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/ Thursday, November 8, 12
  • 20.
    JavaScript that Doesn’tBlock <head> <!-­‐-­‐  Downloads  right  away  -­‐-­‐> <script  src  async></script> <!-­‐-­‐  Waits  to  download  -­‐-­‐> <script  src  defer></script> http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/ Thursday, November 8, 12
  • 21.
    JavaScript that Doesn’tBlock var  script  =  document.createElement("script"); script.type  =  "text/javascript"; script.src  =  "foo.js"; document.getElementsByTagName("head") [0].appendChild(script); http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/ Thursday, November 8, 12
  • 22.
    Stylesheets Block ✤ “Browsers (except Opera) block rendering until all screen CSS arrives. With the worst possible experience: white page.” ✤ “Browsers download CSS they don't need, e.g. print, tv, device- ratio... And most browsers (except Opera and Webkit) block rendering because of these too” ✤ http://www.phpied.com/files/css-loading/mq.php?mq=all http://www.phpied.com/css-and-the-critical-path/ Thursday, November 8, 12
  • 23.
    WebKit <!-­‐-­‐  blocking  stylesheet,  nothing  renders  until  it  is   downloaded  and  parsed  -­‐-­‐>   <link  href="main.css"  rel="stylesheet"> <!-­‐-­‐  non-­‐blocking,  low  download  priority  because  of  the   evaluated  media  query  -­‐-­‐> <link  href="i-­‐want-­‐a-­‐monitor-­‐of-­‐this-­‐size.css"   rel="stylesheet"  media="(min-­‐width:  4000px)"> <!-­‐-­‐  print  stylesheet  is  non-­‐blocking  -­‐-­‐> <link  href="noop.css"  rel="stylesheet"  media="print"> http://www.igvita.com/2012/06/14/debunking-responsive-css-performance-myths/ Thursday, November 8, 12
  • 24.
    Everything Else* <!-­‐-­‐  blocking  stylesheet,  nothing  renders  until  it  is   downloaded  and  parsed  (timeouts  may  vary)  -­‐-­‐>   <link  href="main.css"  rel="stylesheet"> <link  href="i-­‐want-­‐a-­‐monitor-­‐of-­‐this-­‐size.css"   rel="stylesheet"  media="(min-­‐width:  4000px)"> <link  href="noop.css"  rel="stylesheet"  media="print"> Thursday, November 8, 12
  • 25.
    Downloading CSS http://scottjehl.github.com/CSS-Download-Tests/ Thursday, November 8, 12
  • 26.
    Downloading CSS Firefox 16 Opera 12 Safari 6 Chrome 22 Thursday, November 8, 12
  • 27.
    Solutions ✤ CSS is sacred. Choose minimal when possible. ✤ Separate <link> elements for each Media Query ✤ Doesn’t scale if you have a lot of breakpoints. ✤ Good for WebKit, what about everything else? ✤ eCSSential Thursday, November 8, 12
  • 28.
    eCSSential ✤ “Making responsive CSS load the way it should.” ✤ Downloads Blocking CSS that matches media queries ✤ Downloads other CSS async, non-blocking ✤ https://github.com/filamentgroup/eCSSential Thursday, November 8, 12
  • 29.
    matchMedia if  (window.matchMedia("(min-­‐width:  400px)").matches)  {    /*  the  view  port  is  at  least  400  pixels  wide  */ }  else  {    /*  the  view  port  is  less  than  400  pixels  wide  */ } https://developer.mozilla.org/en-US/docs/DOM/window.matchMedia Thursday, November 8, 12
  • 30.
    matchMedia http://caniuse.com/#feat=matchmedia Polyfill: https://github.com/paulirish/matchMedia.js/ Careful with IE8-, the polyfill requires Media Query support Thursday, November 8, 12
  • 31.
    eCSSential <head>        <script>        <!-­‐-­‐  Inline  eCSSential.min.js  -­‐-­‐>        eCSSential({                "all":  "css/all.css",                "(min-­‐width:  20em)":  "css/min-­‐20em.css",                "(min-­‐width:  37.5em)":  "css/min-­‐37.5em.css",                "(min-­‐width:  50em)":  "css/min-­‐50em.css",                "(min-­‐width:  62.5em)":  "css/min-­‐62.5em.css"        });        </script> </head> Thursday, November 8, 12
  • 32.
    eCSSential Demo ✤ http://filamentgroup.github.com/eCSSential/examples/concat/ Thursday, November 8, 12
  • 33.
    Images Don’t Block ✤ Doesn’t mean they get a free pass. Thursday, November 8, 12
  • 34.
    Images Don’t Block ✤ Doesn’t mean they get a free pass. 7 5 3 KB Thursday, November 8, 12
  • 35.
    Downloading Images (CSS) <div  id="test1">        <img  src="images/test1.png"  alt=""  /> </div> @media  all  and  (max-­‐width:  600px)  {        #test1  {  display:none;  } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 36.
    Downloading Images (CSS) PE <div  id="test1"> O        <img  src="images/test1.png"  alt=""  /> N </div> @media  all  and  (max-­‐width:  600px)  {        #test1  {  display:none;  } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 37.
    Downloading Images (CSS) <div  id="test2"></div> #test2  {        background-­‐image:url('images/test2.png');        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test2  {display:none;} } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 38.
    Downloading Images (CSS) PE <div  id="test2"></div> O #test2  {        background-­‐image:url('images/test2.png'); N        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test2  {display:none;} } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 39.
    Downloading Images (CSS) <div  id="test3">        <div></div> </div> #test3  div  {        background-­‐image:url('images/test3.png');        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test3  {                display:none;        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 40.
    Downloading Images (CSS) <div  id="test3">        <div></div> K </div> #test3  div  { O        background-­‐image:url('images/test3.png');        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test3  {                display:none;        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 41.
    Downloading Images (CSS) <div  id="test4"></div> #test4  {        background-­‐image:url('images/test4-­‐desktop.png');        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test4  {                background-­‐image:url('images/test4-­‐mobile.png');        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 42.
    Downloading Images (CSS) <div  id="test4"></div> K #test4  { O        background-­‐image:url('images/test4-­‐desktop.png'); ~        width:200px;        height:75px; } @media  all  and  (max-­‐width:  600px)  {        #test4  {                background-­‐image:url('images/test4-­‐mobile.png');        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 43.
    Downloading Images (CSS) <div  id="test7"></div> #test7  {        background-­‐image:url('images/test7-­‐lowres.png');        width:200px;        height:75px; } @media  only  screen  and  (-­‐webkit-­‐min-­‐device-­‐pixel-­‐ratio:  1.5), only  screen  and  (min-­‐-­‐moz-­‐device-­‐pixel-­‐ratio:  1.5), only  screen  and  (-­‐o-­‐min-­‐device-­‐pixel-­‐ratio:  3/2), only  screen  and  (min-­‐device-­‐pixel-­‐ratio:  1.5)  {        #test7  {                background-­‐image:url('images/test7-­‐highres.png');                width:200px;                height:75px;                /*  Editors  note:  this  should  use  background-­‐size  */        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 44.
    Downloading Images (CSS) <div  id="test7"></div> #test7  {        background-­‐image:url('images/test7-­‐lowres.png');        width:200px; K        height:75px; } O @media  only  screen  and  (-­‐webkit-­‐min-­‐device-­‐pixel-­‐ratio:  1.5), only  screen  and  (min-­‐-­‐moz-­‐device-­‐pixel-­‐ratio:  1.5), only  screen  and  (-­‐o-­‐min-­‐device-­‐pixel-­‐ratio:  3/2), only  screen  and  (min-­‐device-­‐pixel-­‐ratio:  1.5)  {        #test7  {                background-­‐image:url('images/test7-­‐highres.png');                width:200px;                height:75px;                /*  Editors  note:  this  should  use  background-­‐size  */        } } http://timkadlec.com/2012/04/media-query-asset-downloading-results/ Thursday, November 8, 12
  • 45.
    Downloading Images (CSS) ✤ Coming to a browser near you: image-­‐set() ✤ http://blog.cloudfour.com/safari-6-and-chrome-21-add-image-set-to- support-retina-images/ Thursday, November 8, 12
  • 46.
    Downloading <img> ✤ RESPONSIVE IMAGES ✤ Whatever solution you pick, make sure it doesn’t make duplicate requests. Thursday, November 8, 12
  • 47.
    Downloading <img> ✤ If possible, use Vectors (SVG) over Bitmaps (PNG). It’ll look great on HDPI screens. ✤ Vectors are a shortcut for Responsive Images. ✤ Note: Canvas content is bitmapped, but you can redraw at higher resolutions. ✤ Side Note: Font icons are a great scalable alternative to PNG icons Thursday, November 8, 12
  • 48.
    Picturefill ✤ “A Responsive Images approach that you can use today” ✤ https://github.com/scottjehl/picturefill Thursday, November 8, 12
  • 49.
    Picturefill <div  data-­‐picture  data-­‐alt="A  giant  stone  face  at  The  Bayon  temple  in  Angkor  Thom,   Cambodia">        <div  data-­‐src="external/imgs/small.jpg"></div>        <div  data-­‐src="external/imgs/medium.jpg"  data-­‐media="(min-­‐width:  400px)"></div>        <div  data-­‐src="external/imgs/large.jpg"  data-­‐media="(min-­‐width:  800px)"></div>        <div  data-­‐src="external/imgs/extralarge.jpg"  data-­‐media="(min-­‐width:   1000px)"></div>        <!-­‐-­‐  Fallback  content  for  non-­‐JS  browsers.  Same  img  src  as  the  initial,   unqualified  source  element.  -­‐-­‐>        <noscript><img  src="external/imgs/small.jpg"  alt="A  giant  stone  face  at  The   Bayon  temple  in  Angkor  Thom,  Cambodia"></noscript> </div> http://scottjehl.github.com/picturefill/ Thursday, November 8, 12
  • 50.
    Picturefill ✤ data-­‐media="(min-­‐width:  400px)" ✤ Uses  matchMedia. ✤ No  duplicate  requests! Thursday, November 8, 12
  • 51.
    Picturefill (HDPI) <div  data-­‐picture  data-­‐alt="A  giant  stone  face  at  The  Bayon  temple  in  Angkor  Thom,   Cambodia">        <div  data-­‐src="small.jpg"></div>        <div  data-­‐src="small.jpg"                  data-­‐media="(min-­‐device-­‐pixel-­‐ratio:  2.0)"></div>        <div  data-­‐src="medium.jpg"                data-­‐media="(min-­‐width:  400px)"></div>        <div  data-­‐src="medium_x2.jpg"          data-­‐media="(min-­‐width:  400px)  and  (min-­‐device-­‐pixel-­‐ratio:  2.0)"></div>        <div  data-­‐src="large.jpg"                  data-­‐media="(min-­‐width:  800px)"></div>        <div  data-­‐src="large_x2.jpg"            data-­‐media="(min-­‐width:  800px)  and  (min-­‐device-­‐pixel-­‐ratio:  2.0)"></div>            <div  data-­‐src="extralarge.jpg"        data-­‐media="(min-­‐width:  1000px)"></div>        <div  data-­‐src="extralarge_x2.jpg"  data-­‐media="(min-­‐width:  1000px)  and  (min-­‐device-­‐pixel-­‐ratio:  2.0)"></div>          ... </div> http://scottjehl.github.com/picturefill/ Thursday, November 8, 12
  • 52.
    Compressive Images ✤ Pump up the size, pump up the JPEG compression ✤ Scale down in the browser ✤ http://filamentgroup.com/lab/rwd_img_compression/ Thursday, November 8, 12
  • 53.
    Picturefill Simplifes to(HDPI) <div  data-­‐picture  data-­‐alt="A  giant  stone  face  at  The  Bayon  temple  in  Angkor  Thom,   Cambodia">        <div  data-­‐src="small_compressive.jpg"></div>        <div  data-­‐src="medium_compressive.jpg"                data-­‐media="(min-­‐width:  400px)"></div>        <div  data-­‐src="large_compressive.jpg"                  data-­‐media="(min-­‐width:  800px)"></div>        <div  data-­‐src="extralarge_compressive.jpg"        data-­‐media="(min-­‐width:  1000px)"></div>        <!-­‐-­‐  TODO:  adjust  rendered  sizes  -­‐-­‐>        ... </div> ✤ Careful with Memory Consumption! Thursday, November 8, 12
  • 54.
  • 55.
    Buzzkill #1: Advertising ✤ Pit of despair: full of document.write, iframes, blocking JavaScript (errors galore) and general badness. ✤ Inject advertising iframes using JavaScript (after onload) ✤ document.createElement(‘iframe’); Thursday, November 8, 12
  • 56.
    Buzzkill #2: SocialNetworking Widgets Network Requests Size (After GZIP) Compare to jQuery 1.8.2: 32KB ShareThis 19 98.9KB Facebook 3 41.2KB Twitter 5 48KB Google+ 8 30.8KB Thursday, November 8, 12
  • 57.
    SocialCount ✤ 4 KB CSS, 7KB JavaScript (unminified, ✤ Initializes Native Widgets on Hover / Tap ungzipped) for Inline +1 / Like and Tweet. ✤ 2 requests, optional +1 for Counts ✤ In use on f2em.com ✤ Non-Blocking ✤ Sharing still works without JavaScript Thursday, November 8, 12
  • 58.
    SocialCount ng So on C om i ✤ 4 KB CSS, 7KB JavaScript (unminified, ✤ Initializes Native Widgets on Hover / Tap ungzipped) for Inline +1 / Like and Tweet. ✤ 2 requests, optional +1 for Counts ✤ In use on f2em.com ✤ Non-Blocking ✤ Sharing still works without JavaScript Thursday, November 8, 12
  • 59.
  • 60.
    Boston Globe 1.31 MB Advertising, Video Player, Web Fonts, Tracking and Analytics Thursday, November 8, 12
  • 61.
    Disney.com 1.59 MB Advertising, Web Fonts, Tracking and Analytics Thursday, November 8, 12
  • 62.
  • 63.
  • 64.
    Smashing Magazine 1.87 MB Advertising, Web Fonts, Tracking and Analytics Thursday, November 8, 12
  • 65.
    RWD & Performance ✤ “The fastest web site is the one with nothing on it.” ✤ We’re in the problem solving business. ✤ Solutions often require Code. ✤ jQuery and Cross Browser DOM API Compatibility ✤ Solve more problems than you create. Thursday, November 8, 12