46
Building Faster Websites Craig Walker, Chief Technology Officer

Building Faster Websites

Embed Size (px)

DESCRIPTION

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.

Citation preview

Page 1: Building Faster Websites

Building Faster Websites

Craig Walker, Chief Technology Officer

Page 2: Building Faster Websites

What is Xero?

http://www.xero.com/signup/

Page 3: Building Faster Websites

Performance === Usability

Page 4: Building Faster Websites

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

Page 5: Building Faster Websites
Page 6: Building Faster Websites

ReceiveLast Byte

Send Last Byte

Send Data

The HTTP Request

Server

Browser

Establish Connection

InitialConnection

Open Socket

Initial HTTPRequest

First Byte

ReceiveFirst Byte

Send First Byte

Content Download

ISP

Get IP

DNSLookup

Page 7: Building Faster Websites

5%

95%

Page 8: Building Faster Websites

25%

75%

Page 9: Building Faster Websites

Empty Cache Primed Cache

Page 10: Building Faster Websites

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

Page 11: Building Faster Websites

• MySpace's Performance Tracker msfast.myspace.com

• MS Visual Round Trip Analyzer

Lotsa tools!

• HTTPWatch www.httpwatch.com

• AOL PageTest www.webpagetest.org

Page 12: Building Faster Websites

The ones we use at Xero …

• Fiddler www.fiddlertool.com

• Firebug www.getfirebug.com

• YSlow developer.yahoo.com/yslow

Page 13: Building Faster Websites

We don't all run Windows 7 & IE8 …

Browsers

6616

29275

15596

5318

27233

Chrome IE7 IE8Safari 4 Firefox 3

Operating Systems

728

10891

20717

53065

1383

Linux MacOSXVista XPWindows 7

Page 14: Building Faster Websites

Fiddlerdemo

Page 15: Building Faster Websites

The Rules

Page 16: Building Faster Websites

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 …

Page 17: Building Faster Websites

Fly’s down Zipped

Page 18: Building Faster Websites

Turning on HTTP Compression

demo

Page 19: Building Faster Websites

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

Page 20: Building Faster Websites

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

Page 21: Building Faster Websites

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|area|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|col)$/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.createElement(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{if(s){u.setAttribute(p,v[p]);}else{u[p]=v[p];}}}Ext.DomHelper.applyStyles(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.parentNode;}t=k(4,i,r,d);}else{if(p=="tr"){if(q=="beforebegin"){u=s;s=s.parentNode;t=k(3,c,r,m);}else{if(q=="afterend"){u=s.nextSibling;s=s.parentNode;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);}}}else{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

Page 22: Building Faster Websites

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

Page 23: Building Faster Websites

CSS Sprites

• Combine all small images into one large image

• Use CSS to control the displaying of each image

Page 24: Building Faster Websites

The designers want what?

11 images11 HTTP Requests3.3 KB total size

Page 25: Building Faster Websites

Obey your thirst®

1 image1 HTTP Request1.6 KB total size

Page 26: Building Faster Websites

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;}

Page 27: Building Faster Websites

SpriteMedemo

Page 28: Building Faster Websites

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

Page 29: Building Faster Websites

12KB15KB

Page 30: Building Faster Websites

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)

Page 31: Building Faster Websites
Page 32: Building Faster Websites
Page 33: Building Faster Websites

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)

Page 34: Building Faster Websites

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

Page 35: Building Faster Websites

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

Page 36: Building Faster Websites

GETRequest

Response with HTML document

ImagesJSCSS

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

Page 37: Building Faster Websites

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!

Page 38: Building Faster Websites

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

Page 39: Building Faster Websites

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

Page 40: Building Faster Websites

YSlowdemo

Page 41: Building Faster Websites

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

Page 42: Building Faster Websites

Aptimizedemo

Page 43: Building Faster Websites

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

Page 44: Building Faster Websites

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

Page 45: Building Faster Websites

Questions?

Page 46: Building Faster Websites

www.xero.com