Share
Embed
Performance and Responsive Web Design
A 2015 version of my Performance RWD presentation, this time for NebraskaJS Lincoln.
Blog post: http://www.zachleat.com/web/rwd-perf-3/
zachleat
January 15, 2015
Transcript
123 slides
-
Goals Primer RWD !== Media Queries Assets Common Buzzkills and
Tips for faster loading RWD RWD Showcase Showdown. -
RESPONSIVE WEB DESIGN is A Flexible Grid (Fluid: % +
Min Widths) Flexible Media (Images, Video) img { max-‐width: 100%; } FitVids.js (http://fitvidsjs.com/) (Not Just) Media Queries @media (min-‐width: 20em) { /* CSS goes here */ } http://unstoppablerobotninja.com/entry/on-being-responsive -
Ignore Mobile? “Mobile internet adoption has outpaced desktop internet adoption
by eight times.” http://www.lukew.com/ff/entry.asp?993 Alternatives to RWD -
Use a Separate mdot Site Redirects are slow. Maintenance of
UA-Parsing Server Side Content Strategy (Desktop Mode link) Alternatives to RWD -
Redirects are Slow “…redirects slow down the user experience. Inserting
a redirect between the user and the HTML document delays everything in the page…” http://developer.yahoo.com/performance/rules.html#redirects “Minimizing HTTP redirects from one URL to another cuts out additional RTTs and wait time for users.” https://developers.google.com/speed/docs/best-practices/rtt#AvoidRedirects Use a separate mdot Site -
Maintain UA-Parsing Server Side Code WURFL updates about once a
month Use a separate mdot Site http://wurfl.sourceforge.net/ -
“Get to a point with your web strategy where you
don't crap your pants every time Apple has a keynote.” -
“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 -
The Problems Browsers Download and Block Rendering on Unnecessary CSS
Browsers Sometimes Download Unnecessary Images Big Images are Wasted on Small Screens Retina Images are Wasted on <snob>Blurry</snob> Screens -
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/ -
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/ -
JavaScript that Doesn’t Block var script = document.createElement("script"); script.type
= "text/javascript"; script.src = "foo.js"; var ref = document.getElementsByTagName('script')[0]; ref.parentNode.insertBefore(script, ref); http://calendar.perfplanet.com/2010/the-truth-about-non-blocking-javascript/ http://paulirish.com/2011/surefire-dom-element-insertion/ -
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” Demo: http://www.phpied.com/files/css-loading/mq.php?mq=all http://www.phpied.com/css-and-the-critical-path/ -
Blink <!-‐-‐ 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/ -
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"> -
Solutions CSS is sacred. Choose minimal when possible. Separate <link>
elements for each breakpoint Doesn’t scale. Good for WebKit, what about everything else? Separate out and inline your Critical CSS. -
grunt.initConfig({ criticalcss: {
custom: { options: { url: "http://localhost:4000", width: 1200, height: 900, outputfile: "dist/critical.css", filename: "/complete-‐sheet.css" } } }, }); -
<head> … <style> /* inline critical.css here
*/ </style> <script> // loadCSS utility omitted for brevity loadCSS( "complete-‐sheet.css" ); </script> … </head> -
<img> hidden in 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/ Downloading Images -
<img> hidden in 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/ NOPE Downloading Images -
<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/ CSS background image hidden in CSS Downloading Images -
<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/ NOPE CSS background image hidden in CSS Downloading Images -
<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/ CSS background image on child hidden in CSS Downloading Images -
<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/ OK CSS background image on child hidden in CSS Downloading Images -
<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/ CSS background image replaced in CSS Downloading Images -
<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/ ~OK CSS background image replaced in CSS Downloading Images -
<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/ CSS background image replaced in CSS Downloading Images -
<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/ OK CSS background image replaced in CSS Downloading Images -
Downloading Images (CSS) image-‐set() #test { background-‐image: url(assets/no-‐image-‐set.png);
background-‐image: -‐webkit-‐image-‐set(url(assets/test.png) 1x, url(assets/test-‐hires.png) 2x); width:200px; height:75px; } Demo: http://cloudfour.com/examples/image-set/ -
Downloading <img> Vector First (SVG) Responsive images are only for
lowly Bitmaps (PNG, JPEG, GIF) -
<img src="small.jpg" srcset="large.jpg 2x, small.jpg
1x" alt="A rad wolf"> <!-‐-‐ Device Pixel Ratio -‐-‐> -
<img src="small.jpg" srcset="large.jpg 1024w, medium.jpg
640w, small.jpg 320w" alt="A rad wolf"> <!-‐-‐ w is the width of the file (in px) -‐-‐> -
<img src="small.jpg" srcset="large.jpg 1024w, medium.jpg
640w, small.jpg 320w" sizes="(min-‐width: 36em) 33.3vw, 100vw" alt="A rad wolf"> <!-‐-‐ sizes depict the size of the image relative to the viewport -‐-‐> -
Picturefill “A Responsive Images approach that you can use today”
http://scottjehl.github.io/picturefill/ -
Picturefill <picture> <source srcset="examples/images/extralarge.jpg" media="(min-‐ width: 1000px)">
<source srcset="examples/images/large.jpg" media="(min-‐ width: 800px)"> <img srcset="examples/images/medium.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> </picture> http://scottjehl.github.io/picturefill/#examples -
Picturefill (HDPI) <picture> <source srcset="examples/images/large.jpg, examples/ images/extralarge.jpg 2x"
media="(min-‐width: 800px)"> <img srcset="examples/images/small.jpg, examples/ images/medium.jpg 2x" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> </picture> http://scottjehl.github.com/picturefill/ -
Compressive Images Pump up the size, pump up the JPEG
compression Scale down in the browser http://filamentgroup.com/lab/rwd_img_compression/ -
COMPRESSIVe IMAGES Often a smaller file size than a scaled
down (400x300) image Looks better on HDPI screens -
@font-‐face { font-‐family: Open Sans; src:
url("data:application/x-‐font-‐ woff;charset=utf-‐8;base64,...") format("woff"); font-‐weight: 400; font-‐style: normal; } @font-‐face { font-‐family: Open Sans; src: url("data:application/x-‐font-‐ woff;charset=utf-‐8;base64,...") format("woff"); font-‐weight: 700; /* Bold */ font-‐style: normal; } -
var doc = document, docEl =
doc.documentElement; doc.fonts.load("1em Raleway") .then(function() { // The font has loaded. docEl.className += " raleway-‐loaded"; }); -
body { font-‐family: sans-‐serif; } .raleway-‐loaded
body { font-‐family: Raleway, sans-‐serif; } -
Advertising Full of document.write, iframes, blocking JavaScript (errors come for
free) and general badness. Trick: Inject advertising iframes using JavaScript (after onload) document.createElement('iframe'); -
SocialCount Above sample: http://f2em.com/ 3.3KB (GZIP) 1 JS request 1
CSS request 1 optional request for icons 1 optional AJAX request for counts https://github.com/filamentgroup/SocialCount