Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Building Faster Websites
Craig Walker, Chief Technology Officer
What is Xero?
http://www.xero.com/signup/
Performance === Usability
Performance === Money
• Bing: +2s in response time = 4.3% LOSS
of revenue/user
• Google: +500ms in response time = 20%
LES...
Receive
Last Byte
Send
Last Byte
Send Data
The HTTP Request
Server
Browser
Establish
Connection
Initial
Connection
Open So...
5%
95%
25%
75%
Empty Cache Primed Cache
Focus on the front-end
• 75-95% of the end-user response time for
Xero customers was spent on the front
end
• Much easier ...
• MySpace's Performance
Tracker
msfast.myspace.com
• MS Visual Round Trip
Analyzer
Lotsa tools!
• HTTPWatch
www.httpwatch....
The ones we use at Xero …
• Fiddler
www.fiddlertool.com
• Firebug
www.getfirebug.com
• YSlow
developer.yahoo.com/ysl
ow
We don't all run Windows 7 & IE8 …
6616
29275
15596
5318
27233
Browsers
Chrome IE7 IE8
Safari 4 Firefox 3
728
10891
20717
...
Fiddler
The Rules
Zip It!
• Significantly reduces download
size – 60-80% saving on text
based content
• 90% of browsers support
compression
...
Fly’s down Zipped
Turning on HTTP
Compression
Things to be wary of with compression
…
• Make sure you test – don't assume compression
• Approximately 5% of users get un...
Minify all static content
• CSS, JavaScript, XML, JSON, HTML can all be
minified
• Not a replacement for gzipping but is a...
You don't really want people to read your code do
you?
Ext.DomHelper = function(){
var tempTableEl = null;
var emptyTags =...
Reduce HTTP Requests
• Less components means a
faster page
• Every request is an overhead
• Combine scripts
• Combine CSS
...
CSS Sprites
• Combine all small images
into one large image
• Use CSS to control the
displaying of each image
The designers want what?
11 images
11 HTTP Requests
3.3 KB total size
Obey your thirst®
1 image
1 HTTP Request
1.6 KB total size
And the code?
<div class="buttons">
<span class="large green button">
<button type="button">
<span class="checkbox icon">
...
SpriteMe
Optimise images
• Use PNGs instead of GIFs
• Avoid alpha filters – can block rendering and
freeze the browser
• PNG8 is be...
12KB15KB
Maximise Parallel Downloads
• Most browsers are limited to 6 connections total and 2
connections per hostname
Browser Para...
JavaScript external and on the bottom
• Move scripts to external files for both reuse and caching
• Promotes better script...
Maximise the cache
• Understand the ratio of users with cached vs uncached
• Add an Expires header
– Not just for images –...
Use a CDN
• Content Delivery Network
• Distributes content closer to the last mile
• Distribute your static content before...
GET
Request
Response with
HTML document
Images
JS
CSS
How it works:
RegisterCSS("/common/style/xero.css", "screen")
Regist...
Reduce cookie weight
• Cookies are sent back with
every request
• Keep cookie size small and
only store what's required –
...
Preloading …
• Preload components
you’ll need in the future
• Unconditional preload
– Xero login page preloads
all core co...
YSlow
• Firebug extension
• Grades performance – not about
response times but about how
well a site has adopted the
techni...
YSlow
Aptimize
• Plugin that works with both IIS &
Apache
• Merges CSS & JSS files
• Reduces & optimises images with
CSS sprites...
Aptimize
Aptimizing Microsoft
• Microsoft used Aptimize to
speed up
sharepoint.microsoft.com
• HTTP requests reduced
from 96 to 35
...
Things to take away
• Focus on the front-end
• Be an advocate for your users – isn't it nice to
have happy users?
• Faster...
www.xero.com
Building Faster Websites
Building Faster Websites
Building Faster Websites
Building Faster Websites
Upcoming SlideShare
Loading in …5
×

Building Faster Websites

1,735 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
  • Be the first to comment

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

×