Presentation is loading. Please wait.

Presentation is loading. Please wait.

Steve Souders Even Faster Web Sites Disclaimer: This content does not necessarily reflect.

Similar presentations


Presentation on theme: "Steve Souders Even Faster Web Sites Disclaimer: This content does not necessarily reflect."— Presentation transcript:

1 Steve Souders souders@google.com http://stevesouders.com/docs/teched-20090512.ppt Even Faster Web Sites Disclaimer: This content does not necessarily reflect the opinions of my employer.

2 17% 83% iGoogle, primed cache the importance of frontend performance 9%91% iGoogle, empty cache

3 time spent on the frontend Empty CachePrimed Cache www.aol.com97% www.ebay.com95%81% www.facebook.com95%81% www.google.com/search47%0% search.live.com/results67%0% www.msn.com98%94% www.myspace.com98% en.wikipedia.org/wiki94%91% www.yahoo.com97%96% www.youtube.com98%97% April 2008

4 The Performance Golden Rule 80-90% of the end-user response time is spent on the frontend. Start there. greater potential for improvement simpler proven to work

5 14 R ULES 1.M AKE FEWER HTTP REQUESTS 2.U SE A CDN 3.A DD AN E XPIRES HEADER 4.G ZIP COMPONENTS 5.P UT STYLESHEETS AT THE TOP 6.P UT SCRIPTS AT THE BOTTOM 7.A VOID CSS EXPRESSIONS 8.M AKE JS AND CSS EXTERNAL 9.R EDUCE DNS LOOKUPS 10.M INIFY JS 11.A VOID REDIRECTS 12.R EMOVE DUPLICATE SCRIPTS 13.C ONFIGURE ET AGS 14.M AKE AJAX CACHEABLE

6

7

8

9 Sept 2007

10 June 2009

11 Even Faster Web Sites Splitting the initial payload Loading scripts without blocking Coupling asynchronous scripts Positioning inline scripts Sharding dominant domains Flushing the document early Using iframes sparingly Simplifying CSS Selectors Understanding Ajax performance.............Doug Crockford Creating responsive web apps..............Ben Galbraith, Dion Almaer Writing efficient JavaScript................Nicholas Zakas Scaling with Comet........................Dylan Schiemann Going beyond gzipping...............Tony Gentilcore Optimizing images...................Stoyan Stefanov, Nicole Sullivan

12 AOL eBay Facebook MySpace Wikipedia Yahoo! Why focus on JavaScript? YouTube

13 scripts block blocks parallel downloads and rendering 7 secs: IE 8, FF 3.5(?), Chr 2, Saf 4 http://stevesouders.com/cuzillion/?ex=10008 What's Cuzillion? 9 secs: IE 6-7, FF 3.0, Chr 1, Op 9-10, Saf 3

14 a tool for quickly constructing web pages to see how components interact Open Source http://stevesouders.com/cuzillion/ Cuzillion 'cuz there are a zillion pages to check

15 JavaScript Functions Executed before onload www.aol.com115K30% www.ebay.com183K44% www.facebook.com1088K 9% www.google.com/search15K45% search.live.com/results17K24% www.msn.com131K31% www.myspace.com297K18% en.wikipedia.org/wiki114K32% www.yahoo.com321K13% www.youtube.com240K18% 26% avg 252K avg initial payload and execution

16 Splitting the initial payload split your JavaScript between what's needed to render the page and everything else load "everything else" after the page is rendered separate manually (Firebug); tools needed to automate this (Doloto from Microsoft) load scripts without blocking – how?

17 MSN Scripts and other resources downloaded in parallel! How? Secret sauce?! var p= g.getElementsByTagName("HEAD")[0]; var c=g.createElement("script"); c.type="text/javascript"; c.onreadystatechange=n; c.onerror=c.onload=k; c.src=e; p.appendChild(c) MSN.com: parallel scripts

18 Loading Scripts Without Blocking XHR Eval XHR Injection Script in Iframe Script DOM Element Script Defer document.write Script Tag

19 XHR Eval script must have same domain as main page must refactor script var xhrObj = getXHRObject(); xhrObj.onreadystatechange = function() { if ( xhrObj.readyState != 4 ) return; eval(xhrObj.responseText); }; xhrObj.open('GET', 'A.js', true); xhrObj.send(''); http://stevesouders.com/cuzillion/?ex=10009

20 XHR Injection var xhrObj = getXHRObject(); xhrObj.onreadystatechange = function() { if ( xhrObj.readyState != 4 ) return; var se=document.createElement('script'); document.getElementsByTagName('head') [0].appendChild(se); se.text = xhrObj.responseText; }; xhrObj.open('GET', 'A.js', true); xhrObj.send(''); script must have same domain as main page http://stevesouders.com/cuzillion/?ex=10015

21 Script in Iframe <iframe src='A.html' width=0 height=0 frameborder=0 id=frame1> iframe must have same domain as main page must refactor script: // access iframe from main page window.frames[0].createNewDiv(); // access main page from iframe parent.document.createElement('div'); http://stevesouders.com/cuzillion/?ex=10012

22 Script DOM Element var se = document.createElement('script'); se.src = 'http://anydomain.com/A.js'; document.getElementsByTagName('head') [0].appendChild(se); script and main page domains can differ no need to refactor JavaScript http://stevesouders.com/cuzillion/?ex=10010

23 Script Defer only supported in IE (just landed in FF 3.1) script and main page domains can differ no need to refactor JavaScript http://stevesouders.com/cuzillion/?ex=10013

24 document.write Script Tag document.write(" "); parallelization only works in IE parallel downloads for scripts, nothing else all document.write s must be in same script block http://stevesouders.com/cuzillion/?ex=10014

25 browser busy indicators

26 status bar progress bar logocursor block render block onload normal Script Src FFIE,FF FFIE,FF XHR Eval no XHR Injection no Script in Iframe IE,FFFFIE,FFFFnoIE,FF Script DOM Element FF noFF Script Defer FF IE,FF document.write Script Tag FFIE,FF FFIE,FF good to show busy indicators when the user needs feedback bad when downloading in the background

27 Ensure scripts execute in order: necessary when scripts have dependencies IE: http://stevesouders.com/cuzillion/?ex=10017 http://stevesouders.com/cuzillion/?ex=10017 FF: http://stevesouders.com/cuzillion/?ex=10018 http://stevesouders.com/cuzillion/?ex=10018 Avoid scripts executing in order: faster – first script back is executed immediately http://stevesouders.com/cuzillion/?ex=10019 ensure/avoid ordered execution

28 Loading Scripts Without Blocking || down- loads domains can differ existing scripts browser busy ensures order size (bytes) normal Script Src noyes IE,FF ~50 XHR Eval IE,FFno ~500 XHR Injection IE,FFnoyesno ~500 Script in Iframe IE,FFno IE,FFno~50 Script DOM Element IE,FFyes FF ~200 Script Defer IEyes IE,FFIE~50 document.write Script Tag IE * yes IE,FFIE~100 * Only other document.write scripts are downloaded in parallel (in the same script block).

29 and the winner is... XHR Eval XHR Injection Script in iframe Script DOM Element Script Defer Script DOM Element Script Defer Script DOM Element Script DOM Element (FF) Script Defer (IE) XHR Eval XHR Injection Script in iframe Script DOM Element (IE) XHR Injection XHR Eval Script DOM Element (IE) Managed XHR Injection Managed XHR Eval Script DOM Element Managed XHR Injection Managed XHR Eval Script DOM Element (FF) Script Defer (IE) Managed XHR Eval Managed XHR Injection Script DOM Element (FF) Script Defer (IE) Managed XHR Eval Managed XHR Injection different domains same domains no order preserve orderno order no busy show busy no busy preserve order

30 Loading Scripts Without Blocking don't let scripts block other downloads you can still control execution order, busy indicators, and onload event What about inline scripts?

31

32 synchronous JS example: menu.js var aExamples = [ ['couple-normal.php', 'Normal Script Src'], ['couple-xhr-eval.php', 'XHR Eval'],... ['managed-xhr.php', 'Managed XHR'] ]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } init();

33 asynchronous JS example: menu.js var domscript = document.createElement('script'); domscript.src = "menu.js"; document.getElementsByTagName('head')[0].appendChild(domscri pt); var aExamples = [ ['couple-normal.php', 'Normal Script Src'], ['couple-xhr-eval.php', 'XHR Eval'],... ['managed-xhr.php', 'Managed XHR'] ]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } init(); script DOM element approach

34 before after

35 Loading Scripts Without Blocking || down- loads domains can differ existing scripts browser busy ensures order size (bytes) normal Script Src noyes IE,FF ~50 XHR Eval IE,FFno ~500 XHR Injection IE,FFnoyesno ~500 Script in Iframe IE,FFno IE,FFno~50 Script DOM Element IE,FFyes FF ~200 Script Defer IEyes IE,FFIE~50 document.write Script Tag IE * yes IE,FFIE~100 * Only other document.write scripts are downloaded in parallel (in the same script block). !IE

36 what about inlined code that depends on the script?

37 baseline coupling results (not good) Preserve Execution Order Load Script & Image in Parallel normal Script Src allIE8, Saf4, Chr2 XHR Eval -all XHR Injection -all Script in Iframe -all Script DOM Element FF, OpIE, FF, Saf, Chr Script Defer FF, Saf, Chr, OpIE, (Saf4, Chr2) * document.write Script Tag allSaf4, Chr2 * Scripts download in parallel regardless of the Defer attribute. need a way to load scripts asynchronously AND preserve order

38 coupling techniques hardcoded callback window onload timer degrading script tags script onload

39 technique 1: hardcoded callback var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } var domscript = document.createElement('script'); domscript.src = "menu.js"; document.getElementsByTagName('head')[0].appendChild(domscri pt); init() is called from within menu.js not very flexible doesn't work for 3 rd party scripts

40 technique 2: window onload var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } if ( window.addEventListener ) { window.addEventListener("load", init, false); } else if ( window.attachEvent ) { window.attachEvent("onload", init); } init() is called at window onload must use async technique that blocks onload: Script in Iframe does this across most browsers init() called later than necessary

41 technique 3: timer var domscript = document.createElement('script'); domscript.src = "menu.js"; document.getElementsByTagName('head')[0].appendChild(domscript); var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } function initTimer(interval) { if ( "undefined" === typeof(EFWS) ) { setTimeout(initTimer, interval); } else { init(); } initTimer(300); load if interval too low, delay if too high slight increased maintenance – EFWS

42 John Resig's degrading script tags var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } init(); at the end of menu-degrading.js: var scripts = document.getElementsByTagName("script"); var cntr = scripts.length; while ( cntr ) { var curScript = scripts[cntr-1]; if (curScript.src.indexOf("menu-degrading.js") != -1) { eval( curScript.innerHTML ); break; } cntr--; } http://ejohn.org/blog/degrading-script-tags/ cleaner clearer safer – inlined code not called if script fails no browser supports it

43 technique 4: degrading script tags var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } var domscript = document.createElement('script'); domscript.src = "menu-degrading.js"; if ( -1 != navigator.userAgent.indexOf("Opera") ) { domscript.innerHTML = "init();"; } else { domscript.text = "init();"; } document.getElementsByTagName('head')[0].appendChild(domscript); elegant, flexible (cool!) not well known doesn't work for 3 rd party scripts (unless...)

44 technique 5: script onload var aExamples = [['couple-normal.php', 'Normal Script Src'],...]; function init() { EFWS.Menu.createMenu('examplesbtn', aExamples); } var domscript = document.createElement('script'); domscript.src = "menu.js"; domscript.onloadDone = false; domscript.onload = function() { if ( ! domscript.onloadDone ) { init(); } domscript.onloadDone = true; }; domscript.onreadystatechange = function() { if ( "loaded" === domscript.readyState ) { if ( ! domscript.onloadDone ) { init(); } domscript.onloadDone = true; } document.getElementsByTagName('head')[0].appendChild(domscript); pretty nice, medium complexity

45 what about multiple scripts that depend on each other, and inlined code that depends on the scripts? two solutions: Managed XHR DOM Element and Doc Write

46 multiple script example: menutier.js var aRaceConditions = [['couple-normal.php', 'Normal...]; var aWorkarounds = [['hardcoded-callback.php', 'Hardcod...]; var aMultipleScripts = [['managed-xhr.php', 'Managed XH...]; var aLoadScripts = [['loadscript.php', 'loadScript'],...]; var aSubmenus = [["Race Conditions", aRaceConditions], ["Workarounds", aWorkarounds], ["Multiple Scripts", aMultipleScripts], ["General Solution", aLoadScripts]]; function init() { EFWS.Menu.createTieredMenu('examplesbtn', aSubmenus); }

47 technique 1: managed XHR var aRaceConditions = [['couple-normal.php', 'Normal...]; var aWorkarounds = [['hardcoded-callback.php', 'Hardcod...]; var aMultipleScripts = [['managed-xhr.php', 'Managed XH...]; var aLoadScripts = [['loadscript.php', 'loadScript'],...]; var aSubmenus = [["Race Conditions", aRaceConditions],...]; function init() { EFWS.Menu.createTieredMenu('examplesbtn', aSubmenus); } EFWS.Script.loadScriptXhrInjection("menu.js", null, true); EFWS.Script.loadScriptXhrInjection("menutier.js", init, true); XHR Injection asynchronous technique does not preserve order – we have to add that before after

48 EFWS.loadScriptXhrInjection // Load an external script. // Optionally call a callback and preserve order. loadScriptXhrInjection: function(url, onload, bOrder) { var iQ = EFWS.Script.queuedScripts.length; if ( bOrder ) { var qScript = { response: null, onload: onload, done: false }; EFWS.Script.queuedScripts[iQ] = qScript; } var xhrObj = EFWS.Script.getXHRObject(); xhrObj.onreadystatechange = function() { if ( xhrObj.readyState == 4 ) { if ( bOrder ) { EFWS.Script.queuedScripts[iQ].response = xhrObj.responseText; EFWS.Script.injectScripts(); } else { eval(xhrObj.responseText); if ( onload ) { onload(); } }; xhrObj.open('GET', url, true); xhrObj.send(''); } process queue (next slide)or... eval now, call callback save response to queue add to queue (if bOrder)

49 EFWS.injectScripts // Process queued scripts to see if any are ready to inject. injectScripts: function() { var len = EFWS.Script.queuedScripts.length; for ( var i = 0; i < len; i++ ) { var qScript = EFWS.Script.queuedScripts[i]; if ( ! qScript.done ) { if ( ! qScript.response ) { // STOP! need to wait for this response break; } else { eval(qScript.response); if ( qScript.onload ) { qScript.onload(); } qScript.done = true; } ready for this script, eval and call callback bail – need to wait to preserve order if not yet injected preserves external script ordernon-blocking works in all browserscouples with inlined code works with scripts across domains

50 technique 2: DOM Element and Doc Write Preserve Execution Order Load Scripts in Parallel Load Script & Image in Parallel Script DOM Element FF, Op FF, Op, IE, Saf, Chr FF, IE, Saf, Chr Script Defer IE, Saf, Chr, FF, Op IE document.write Script Tag IE, Saf, Chr, FF, Op IE, Op Firefox & Opera – use Script DOM Element IE – use document.write Script Tag Safari, Chrome – no benefit; rely on Safari 4 and Chrome 2

51 EFWS.loadScripts loadScripts: function(aUrls, onload) { // first pass: see if any of the scripts are on a different domain var nUrls = aUrls.length; var bDifferent = false; for ( var i = 0; i < nUrls; i++ ) { if ( EFWS.Script.differentDomain(aUrls[i]) ) { bDifferent = true; break; } // pick the best loading function var loadFunc = EFWS.Script.loadScriptXhrInjection; if ( bDifferent ) { if ( -1 != navigator.userAgent.indexOf('Firefox') || -1 != navigator.userAgent.indexOf('Opera') ) { loadFunc = EFWS.Script.loadScriptDomElement; } else { loadFunc = EFWS.Script.loadScriptDocWrite; } // second pass: load the scripts for ( var i = 0; i < nUrls; i++ ) { loadFunc(aUrls[i], ( i+1 == nUrls ? onload : null ), true); }

52 multiple scripts with dependencies var aRaceConditions = [['couple-normal.php', 'Normal...]; var aWorkarounds = [['hardcoded-callback.php', 'Hardcod...]; var aMultipleScripts = [['managed-xhr.php', 'Managed XH...]; var aLoadScripts = [['loadscript.php', 'loadScript'],...]; var aSubmenus = [["Race Conditions", aRaceConditions],...]; function init() { EFWS.Menu.createTieredMenu('examplesbtn', aSubmenus); } EFWS.Script.loadScripts(["menu.js", "menutier.js"], init); scripts on same domain: order preserved, no blocking scripts on different domain: order preserved: all loads scripts in parallel: all except Saf3, Chr1 load script and image in parallel: FF, Saf4, Chr2

53 asynchronous scripts wrap-up Technique Preserve Order Load Scripts in Parallel Load Script & Image in Parallel single script Script DOM Element na all multiple scripts, no dependencies Script DOM Element naall multiple scripts, dependencies, same domain Managed XHRall multiple scripts, dependencies, same domain Script DOM Element (FF, Op), Doc Write (IE, Saf, Chr) all !Saf3, !Chr1 FF, Saf4, Chr2

54 case study: Google Analytics recommended pattern: 1 var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); var pageTracker = _gat._getTracker("UA-xxxxxx-x"); pageTracker._trackPageview(); document.write Script Tag approach blocks other resources 1 http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55488

55 case study: dojox.analytics.Urchin 1 _loadGA: function(){ var gaHost = ("https:" == document.location.protocol) ? "https://ssl." : "http://www."; dojo.create('script', { src: gaHost + "google-analytics.com/ga.js" }, dojo.doc.getElementsByTagName("head")[0]); setTimeout(dojo.hitch(this, "_checkGA"), this.loadInterval); }, _checkGA: function(){ setTimeout(dojo.hitch(this, !window["_gat"] ? "_checkGA" : "_gotGA"), this.loadInterval); }, _gotGA: function(){ this.tracker = _gat._getTracker(this.acct);... } Script DOM Element approach "timer" coupling technique (script onload better) 1 http://docs.dojocampus.org/dojox/analytics/Urchin

56 asynchronous loading & coupling async technique: Script DOM Element easy, cross-browser doesn't ensure script order coupling technique: script onload fairly easy, cross-browser ensures execution order for external script and inlined code multiple interdependent external and inline scripts: much more complex (see hidden slides) concatenate your external scripts into one!

57 bad: stylesheet followed by inline script browsers download stylesheets in parallel with other resources that follow......unless the stylesheet is followed by an inline script http://stevesouders.com/cuzillion/?ex=10021 best to move inline scripts above stylesheets or below other resources use Link, not @import

58 eBay MSN MySpace Wikipedia mispositioned inline scripts

59 Positioning Inline Scripts remember inline scripts carry a cost avoid long-executing inline scripts don't put inline scripts between stylesheets and other resources

60 Simplifying CSS Selectors #toc > LI { font-weight: bold; } combinator simple selectors selector declaration block rule

61 types of CSS selectors ID selectors #toc { margin-left: 20px; } element whose ID attribute has the value "toc" class selectors.chapter { font-weight: bold; } elements with class=chapter type selectors A { text-decoration: none; } all A elements in the document tree http://www.w3.org/TR/CSS2/selector.html

62 types of CSS selectors adjacent sibling selectors H1 + #toc { margin-top: 40px; } an element with ID=toc that immediately follows an H1 child selectors #toc > LI { font-weight: bold; } all LI elements whose parent has id="toc" descendant selectors #toc A { color: #444; } all A elements that have id="toc" as an ancestor

63 types of CSS selectors universal selectors * { font-family: Arial; } all elements attribute selectors [href="#index"] { font-style: italic; } all elements where the href attribute is "#index" psuedo classes and elements A:hover { text-decoration: underline; } non-DOM behavior others: :visited, :link, :active, :focus, :first-child, :before, :after

64 writing efficient CSS https://developer.mozilla.org/en/Writing_Efficient_CSS "The style system matches a rule by starting with the rightmost selector and moving to the left through the rule's selectors. As long as your little subtree continues to check out, the style system will continue moving to the left until it either matches the rule or bails out because of a mismatch." #toc > LI { font-weight: bold; } find every LI whose parent is id="toc" #toc A { color: #444; } find every A and climb its ancestors until id="toc" or DOM root (!) is found

65 writing efficient CSS 1.avoid universal selectors 2.don't qualify ID selectors bad: DIV #navbar {} good: #navbar {} 3.don't qualify class selectors bad: LI.tight {} good:.li-tight {} 4.make rules as specific as possible bad: #navbar A {} good:.a-navbar {} https://developer.mozilla.org/en/Writing_Efficient_CSS

66 writing efficient CSS 5.avoid descendant selectors bad: UL LI A {} better: UL > LI > A {} 6.avoid tag-child selectors bad: UL > LI > A {} best:.li-anchor {} 7.be wary of child selectors 8.rely on inheritance http://www.w3.org/TR/CSS21/propidx.html https://developer.mozilla.org/en/Writing_Efficient_CSS David Hyatt 4/21/2000

67 Testing CSS Performance 20K TD elements http://jon.sykes.me/152/testing-css-performance-pt-2

68 testing massive CSS 20K A elements no style: control tag: A {} class:.a00001 {}.a20000 {} descender: DIV DIV DIV P A.a00001 {} child: DIV > DIV > DIV > P > A.a00001 {} http://jon.sykes.me/153/more-css-performance-testing-pt-3

69 CSS performance isn't linear IE 7 "cliff" at 18K rules

70 real world levels of CSS # Rules# elements Avg Depth AOL2289162813 eBay30558814 Facebook2882196617 Google Search925528 Live Search37644912 MSN.com103888611 MySpace9324449 Wikipedia795133310 Yahoo!80056413 YouTube8218179 average103392312

71 testing typical CSS "costly"selectors aren't always costly (at typical levels) are these selectors "costly"? DIV DIV DIV P A.class0007 {... } 1K rules (vs. 20K) same amount of CSS in all test pages 30 ms avg delta http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

72 testing expensive selectors 1K rules (vs. 20K) same amount of CSS in all test pages 2126 ms avg delta! truly expensive selector A.class0007 * {... } compare to: DIV DIV DIV P A.class0007 {... } the key is the key selector – the rightmost argument

73 CSS3 selectors (bad) more David Hyatt: "The sad truth about CSS3 selectors is that they really shouldnt be used at all if you care about page performance. Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers." http://shauninman.com/archive/2008/05/05/css_qualif ied_selectors#comment_3942

74 selectors to avoid A.class0007 DIV {... } #id0007 > A {... }.class0007 [href] {... } DIV:first-child {... }

75 reflow time vs. load time reflow – time to apply CSS, re-layout elements, and repaint triggered by DHTML: elem.className = "newclass"; elem.style.cssText = "color: red"; elem.style.padding = "8px"; elem.style.display = ""; reflow can happen multiple times for long- lasting Web 2.0 apps

76 reflow time by browser reflow performance varies by browser and action "1x" is 1-6 seconds depending on browser (1K rules) DHTML actionChr1Chr2FF2FF3IE6,7IE 8OpSaf3Saf4 className1x display none----1x---- display default1x 2x1x - visibility hidden1x - visibility visible1x - padding--1x2x4x --- width length--1x2x1x - - width percent--1x2x1x - - width default1x- 2x1x - - background--1x ---- font-size1x 2x1x -

77 Simplifying CSS Selectors efficient CSS comes at a cost – page weight focus optimization on selectors where the key selector matches many elements reduce the number of selectors

78 takeaways focus on the frontend run YSlow: http://developer.yahoo.com/yslow http://developer.yahoo.com/yslow speed matters

79 impact on revenue Google: Yahoo: Amazon: 1 http://home.blarg.net/~glinden/StanfordDataMining.2006-11-29.ppt 2 http://www.slideshare.net/stoyan/yslow-20-presentation +500 ms -20% traffic 1 +400 ms -5-9% full-page traffic 2 +100 ms -1% sales 1

80 cost savings hardware – reduced load bandwidth – reduced response size http://billwscott.com/share/presentations/2008/stanford/HPWP-RealWorld.pdf

81 if you want better user experience more revenue reduced operating expenses the strategy is clear Even Faster Web Sites

82 Steve Souders souders@google.com http://stevesouders.com/docs/teched-20090512.ppt


Download ppt "Steve Souders Even Faster Web Sites Disclaimer: This content does not necessarily reflect."

Similar presentations


Ads by Google