Building Faster Websites

1,597 views
1,535 views

Published on

This is my latest version of my client side performance presentations. This has been presented at TechEd NZ 2009 & to a couple of .NET user groups around NZ. This presentation focuses on the basics of client-side performance tuning.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,597
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
43
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Building Faster Websites

  1. 1. Building Faster Websites Craig Walker, Chief Technology Officer
  2. 2. What is Xero? http://www.xero.com/signup/
  3. 3. Performance === Usability
  4. 4. Performance === Money • Bing: +2s in response time = 4.3% LOSS of revenue/user • Google: +500ms in response time = 20% LESS traffic • Amazon: +100ms in response time = 1% LESS sales • Shopzilla: +5s response time led to 12% increase in revenue & 25% increase in page views
  5. 5. Receive Last Byte Send Last Byte Send Data The HTTP Request Server Browser Establish Connection Initial Connection Open Socket Initial HTTP Request First Byte Receive First Byte Send First Byte Content Download ISP Get IP DNS Lookup
  6. 6. 5% 95%
  7. 7. 25% 75%
  8. 8. Empty Cache Primed Cache
  9. 9. Focus on the front-end • 75-95% of the end-user response time for Xero customers was spent on the front end • Much easier to optimise than server side performance • Greater potential for improvement – especially from a front-end users point of view
  10. 10. • MySpace's Performance Tracker msfast.myspace.com • MS Visual Round Trip Analyzer Lotsa tools! • HTTPWatch www.httpwatch.com • AOL PageTest www.webpagetest.org
  11. 11. The ones we use at Xero … • Fiddler www.fiddlertool.com • Firebug www.getfirebug.com • YSlow developer.yahoo.com/ysl ow
  12. 12. We don't all run Windows 7 & IE8 … 6616 29275 15596 5318 27233 Browsers Chrome IE7 IE8 Safari 4 Firefox 3 728 10891 20717 53065 1383 Operating Systems Linux MacOSX Vista XP Windows 7
  13. 13. Fiddler
  14. 14. The Rules
  15. 15. Zip It! • Significantly reduces download size – 60-80% saving on text based content • 90% of browsers support compression • Benefits users & you too: – Reduces traffic costs – Doesn’t require code change • Zip everything you can – html, aspx, js, css, xml, txt, json, ashx …
  16. 16. Fly’s down Zipped
  17. 17. Turning on HTTP Compression
  18. 18. Things to be wary of with compression … • Make sure you test – don't assume compression • Approximately 5% of users get uncompressed responses • Browsers (& other applications) indicate compression support by sending Accept-Encoding: gzip, deflate and responding with Content-Encoding: gzip • Some client software (anti-virus, anti-phishing) and proxy servers can strip Accept-Encoding • If Accept-Encoding is missing let your users know! • Use Advanced Logging for IIS7 to track request & response headers http://www.iis.net/extensions/advancedlogging
  19. 19. Minify all static content • CSS, JavaScript, XML, JSON, HTML can all be minified • Not a replacement for gzipping but is a perfect accompaniment to it (we've seen up to 50% extra savings) • No shortage of tools: – JSMin – CSSTidy – YUI Compressor • JavaScript obfuscation can also be useful – just test that your app still works afterwards
  20. 20. You don't really want people to read your code do you? Ext.DomHelper = function(){ var tempTableEl = null; var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|ar ea|param|col)$/i; var tableRe = /^table|tbody|tr|td$/i; var createHtml = function(o){ if(typeof o == 'string'){ return o; } var b = ""; if (Ext.isArray(o)) { for (var i = 0, l = o.length; i < l; i++) { b += createHtml(o[i]); } return b; } if(!o.tag){ o.tag = "div"; } b += "<" + o.tag; for(var attr in o){ if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue; if(attr == "style"){ var s = o["style"]; if(typeof s == "function"){ s = s.call(); } if(typeof s == "string"){ b += ' style="' + s + '"'; }else if(typeof s == "object"){ Ext.DomHelper=function(){var n=null;var g=/^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|co l)$/i;var b=/^table|tbody|tr|td$/i;var a=function(w){if(typeof w=="string"){return w;}var q="";if(Ext.isArray(w)){for(var u=0,r=w.length;u<r;u++){q+=a(w[u]);}return q;}if(!w.tag){w.tag="div";}q+="<"+w.tag;for(var p in w){if(p=="tag"||p=="children"||p=="cn"||p=="html"||typeof w[p]=="function"){continue;}if(p=="style"){var v=w["style"];if(typeof v=="function"){v=v.call();}if(typeof v=="string"){q+=' style="'+v+'"';}else{if(typeof v=="object"){q+=' style="';for(var t in v){if(typeof v[t]!="function"){q+=t+":"+v[t]+";";}}q+='"';}}}else{if(p=="cls"){q+= ' class="'+w["cls"]+'"';}else{if(p=="htmlFor"){q+=' for="'+w["htmlFor"]+'"';}else{q+=" "+p+'="'+w[p]+'"';}}}}if(g.test(w.tag)){q+="/>";}else{q+=">";var x=w.children||w.cn;if(x){q+=a(x);}else{if(w.html){q+=w.html;}}q+="</" +w.tag+">";}return q;};var o=function(v,q){var u;if(Ext.isArray(v)){u=document.createDocumentFragment();for(var t=0,r=v.length;t<r;t++){o(v[t],u);}}else{if(typeof v=="string"){u=document.createTextNode(v);}else{u=document.createElem ent(v.tag||"div");var s=!!u.setAttribute;for(var p in v){if(p=="tag"||p=="children"||p=="cn"||p=="html"||p=="style"||typeof v[p]=="function"){continue;}if(p=="cls"){u.className=v["cls"];}else{i f(s){u.setAttribute(p,v[p]);}else{u[p]=v[p];}}}Ext.DomHelper.applySty les(u,v.style);var w=v.children||v.cn;if(w){o(w,u);}else{if(v.html){u.innerHTML=v.html;} }}}if(q){q.appendChild(u);}return u;};var k=function(v,t,r,u){n.innerHTML=[t,r,u].join("");var p=- 1,q=n;while(++p<v){q=q.firstChild;}return q;};var l="<table>",e="</table>",c=l+"<tbody>",m="</tbody>"+e,i=c+"<tr>",d="< /tr>"+m;var h=function(p,q,s,r){if(!n){n=document.createElement("div");}var t;var u=null;if(p=="td"){if(q=="afterbegin"||q=="beforeend"){return;}if(q== "beforebegin"){u=s;s=s.parentNode;}else{u=s.nextSibling;s=s.parentNod e;}t=k(4,i,r,d);}else{if(p=="tr"){if(q=="beforebegin"){u=s;s=s.parent Node;t=k(3,c,r,m);}else{if(q=="afterend"){u=s.nextSibling;s=s.parentN ode;t=k(3,c,r,m);}else{if(q=="afterbegin"){u=s.firstChild;}t=k(4,i,r, d);}}}else{if(p=="tbody"){if(q=="beforebegin"){u=s;s=s.parentNode;t=k (2,l,r,e);}else{if(q=="afterend"){u=s.nextSibling;s=s.parentNode;t=k( 2,l,r,e);}else{if(q=="afterbegin"){u=s.firstChild;}t=k(3,c,r,m);}}}el se{if(q=="beforebegin"||q=="afterend"){return;}if(q=="afterbegin"){u= s.firstChild;}t=k(2,l,r,e);}}}s.insertBefore(t,u);return 955KB -> 265KB 539KB -> 141KB
  21. 21. Reduce HTTP Requests • Less components means a faster page • Every request is an overhead • Combine scripts • Combine CSS • Combine images into CSS Sprites • Don’t rely on cache: 304’s are still requests
  22. 22. CSS Sprites • Combine all small images into one large image • Use CSS to control the displaying of each image
  23. 23. The designers want what? 11 images 11 HTTP Requests 3.3 KB total size
  24. 24. Obey your thirst® 1 image 1 HTTP Request 1.6 KB total size
  25. 25. And the code? <div class="buttons"> <span class="large green button"> <button type="button"> <span class="checkbox icon"> Approve </span> </button> </span> <span class="large blue button"> <button type="button"> <span> Save </span> </button> </span> <span class="large red button"> <button type="button"> <span class="delete icon"> Delete </span> </button> </span> <span class="medium gray button"> <button type="button"> <span class="delete icon"> Cancel </span> </button> </span> </div> .buttons span.button { background:transparent url(buttons.png) no-repeat 0 0; } .buttons span.button button, .buttons span.button a { background:transparent url(buttons.png) no-repeat 100% -120px; } .buttons span.blue { background-position: 0 -30px; } .buttons span.blue button, .buttons span.blue a { background-position: 100% -150px; } .buttons span.red { background-position: 0 -60px; } .buttons span.red button, .buttons span.red a { background-position: 100% -180px; } .buttons span.green { background-position: 0 -90px; } .buttons span.green button, .buttons span.green a { background-position: 100% -210px; }
  26. 26. SpriteMe
  27. 27. Optimise images • Use PNGs instead of GIFs • Avoid alpha filters – can block rendering and freeze the browser • PNG8 is best and supported by IE6 (yes – even with transparency • Optimise further with tools like PNGOUT • Make sure you have a favicon.ico: • Every browser will request it • Best not to respond with a 404 • Make it small and cacheable
  28. 28. 12KB15KB
  29. 29. Maximise Parallel Downloads • Most browsers are limited to 6 connections total and 2 connections per hostname Browser Parallel Downloads Firefox 3.x 6 Internet Explorer 7 2 Internet Explorer 8 6 Safari 3.x 4 Safari 4 4 Chrome 4 • Increase the number of hostnames to increase the number of parallel downloads • Don't overdo it! (DNS lookups are expensive so limit to 2-4 domains)
  30. 30. JavaScript external and on the bottom • Move scripts to external files for both reuse and caching • Promotes better script design • Push scripts as low as possible – Often difficult with document.write or with inline calls requiring loaded JavaScript – Be pragmatic – think about splitting JavaScript into “must be loaded” and “can be loaded on demand” • Scripts will block both downloading and rendering until parsed • Remove duplicate scripts (IE has a habit of downloading them again)
  31. 31. Maximise the cache • Understand the ratio of users with cached vs uncached • Add an Expires header – Not just for images – should be used on all static content – Set a “Never expire” or far future expires policy if you can – Reduces HTTP requests – once component is served, the browser never asks for it again – Date stamping in file names makes it easier • Remove ETags – ETags are another caching mechanism – sent with every request – Uniquely created per web server – not good in web farms – Just turn them off and use Expires headers instead
  32. 32. Use a CDN • Content Delivery Network • Distributes content closer to the last mile • Distribute your static content before distributing your dynamic content • Akamai most popular but expensive for small sites • Xero utilises a rudimentary CDN using IP lookup to determine location
  33. 33. GET Request Response with HTML document Images JS CSS How it works: RegisterCSS("/common/style/xero.css", "screen") RegisterJavascript("/common/scripts/xero.js") <link rel="stylesheet" type="text/css" media="screen" href="https://nzs1.xero.com/common/style/xero.css" /> <script type="text/javascript" src="https://nzs2.xero.com/common/scripts/xero.js"> </script> Get location from IP
  34. 34. Reduce cookie weight • Cookies are sent back with every request • Keep cookie size small and only store what's required – use server-side storage for everything else • Consider cookie free domains for static content • And while we're at it – reduce ViewState too!
  35. 35. Preloading … • Preload components you’ll need in the future • Unconditional preload – Xero login page preloads all core components so that the dashboard experience is better • Conditional preload – Often based on where you think a user might go to next
  36. 36. YSlow • Firebug extension • Grades performance – not about response times but about how well a site has adopted the techniques suggested • Response time inversely proportional to YSlow score – get as close to A as possible to get the maximum performance gain
  37. 37. YSlow
  38. 38. Aptimize • Plugin that works with both IIS & Apache • Merges CSS & JSS files • Reduces & optimises images with CSS sprites & CSS inlining • Compresses content with minification • Improves caching • Used by over 300 websites & intranets • And it does all this in real-time! www.aptimize.com
  39. 39. Aptimize
  40. 40. Aptimizing Microsoft • Microsoft used Aptimize to speed up sharepoint.microsoft.com • HTTP requests reduced from 96 to 35 • Sped up first view, repeat view and start render by over 50% • YSlow went from an E to a B
  41. 41. Things to take away • Focus on the front-end • Be an advocate for your users – isn't it nice to have happy users? • Faster web sites lead to: – Better user experience – Reduced operating expenses – Increase revenue
  42. 42. www.xero.com

×