Even Faster Web Sites http://stevesouders.com/docs/jquery-20090913.ppt Disclaimer: This content does not necessarily reflect the opinions of my employer. the importance of frontend performance 9% 17% 91% 83% iGoogle, primed cache iGoogle, empty cache 14 RULES 1. MAKE FEWER HTTP REQUESTS 2. USE A CDN 3. ADD AN EXPIRES HEADER 4. GZIP COMPONENTS 5. PUT STYLESHEETS AT THE TOP 6. PUT SCRIPTS AT THE BOTTOM 7. AVOID CSS EXPRESSIONS 8. MAKE JS AND CSS EXTERNAL 9. REDUCE DNS LOOKUPS 10.MINIFY JS 11.AVOID REDIRECTS 12.REMOVE DUPLICATE SCRIPTS 13.CONFIGURE ETAGS 14.MAKE AJAX CACHEABLE Sept 2007 June 2009 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 Why focus on JavaScript? Yahoo! Wikipedia eBay AOL MySpace YouTube Facebook scripts block <script src="A.js"> blocks parallel downloads and rendering 9 secs: IE 6-7, FF 3.0, Chr 1, Op 9-10, Saf 3 7 secs: IE 8, FF 3.5, Chr 2, Saf 4 initial payload and execution JavaScript Functions Executed before onload www.aol.com www.ebay.com www.facebook.com www.google.com/search 115K 183K 1088K 15K 30% 44% 9% 45% search.live.com/results www.msn.com www.myspace.com en.wikipedia.org/wiki 17K 131K 297K 114K 24% 31% 18% 32% www.yahoo.com www.youtube.com 321K 240K 252K avg 13% 18% 26% avg 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? MSN.com: parallel scripts 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) Loading Scripts Without Blocking XHR Eval XHR Injection Script in Iframe Script DOM Element Script Defer document.write Script Tag XHR Eval var xhrObj = getXHRObject(); xhrObj.onreadystatechange = function() { if ( xhrObj.readyState != 4 ) return; eval(xhrObj.responseText); }; xhrObj.open('GET', 'A.js', true); xhrObj.send(''); script must have same domain as main page must refactor script 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 Script in Iframe <iframe src='A.html' width=0 height=0 frameborder=0 id=frame1></iframe> 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'); 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 Script Defer <script defer src='A.js'></script> supported in IE and FF 3.1+ script and main page domains can differ no need to refactor JavaScript document.write Script Tag document.write("<script type='text/javascript' src='A.js'> <\/script>"); parallelization only works in IE parallel downloads for scripts, nothing else all document.writes must be in same script block Load Scripts Without Blocking || domains existing browser ensures downcan scripts busy order loads differ normal Script Src XHR Eval XHR Injection Script in Iframe Script DOM Element Script Defer document.write Script Tag *Only size (bytes) no yes yes IE,FF IE,FF ~50 IE,FF no no no no ~500 IE,FF no yes no no ~500 IE,FF no no IE,FF no ~50 IE,FF yes yes FF FF ~200 IE yes yes IE,FF IE ~50 IE* yes yes IE,FF IE ~100 other document.write scripts are downloaded in parallel (in the same script block). and the winner is... XHR Eval XHR Injection Script in iframe Script DOM Element Script Defer same domains different domains Script DOM Element Script Defer no order no order preserve order XHR Eval XHR Injection Script in iframe Script DOM Element (IE) preserve order Script DOM Element (FF) Script Defer (IE) Managed XHR Eval Managed XHR Injection Script DOM Element no busy Script DOM Element (FF) Script Defer (IE) Managed XHR Injection Managed XHR Eval no busy XHR Injection XHR Eval Script DOM Element (IE) show busy Managed XHR Injection Managed XHR Eval Script DOM Element show busy Script DOM Element (FF) Script Defer (IE) Managed XHR Eval Managed XHR Injection asynchronous JS example: menu.js script DOM element approach <script type="text/javascript"> 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> before after Loading Scripts Without Blocking || domains existing browser ensures downcan scripts busy order loads differ normal Script Src XHR Eval XHR Injection Script in Iframe Script DOM Element Script Defer document.write Script Tag *Only size (bytes) no yes yes IE,FF IE,FF ~50 IE,FF no no no no ~500 IE,FF no yes no no ~500 IE,FF no no IE,FF no ~50 IE,FF yes yes FF IE yes yes IE,FF FF !IE ~200 IE ~50 IE* yes yes IE,FF IE other document.write scripts are downloaded in parallel (in the same script block). ~100 what about inlined code that depends on the script? coupling techniques hardcoded callback window onload timer degrading script tags script onload technique 5: script onload <script type="text/javascript"> 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); </script> pretty nice, medium complexity 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! takeaways focus on the frontend run YSlow (http://developer.yahoo.com/yslow) and Page Speed! (http://code.google.com/speed/page-speed/) speed matters impact on revenue Bing: +2000 ms -4.3% revenue/user1 Yahoo: +400 ms -5-9% full-page traffic 2 Google: +400 ms -0.59% searches/user1 AOL: fastest users +50% page views3 Shopzilla: -5000 ms +7-12% revenue4 1 2 3 4 http://en.oreilly.com/velocity2009/public/schedule/detail/8523 http://www.slideshare.net/stoyan/yslow-20-presentation http://en.oreilly.com/velocity2009/public/schedule/detail/7579 http://en.oreilly.com/velocity2009/public/schedule/detail/7709 cost savings hardware – reduced load Shopzilla – 50% fewer servers bandwidth – reduced response size http://billwscott.com/share/presentations/2008/stanford/HPWP-RealWorld.pdf if you want better user experience more revenue reduced operating costs the strategy is clear Even Faster Web Sites book signing now Steve Souders souders@google.com http://stevesouders.com/docs/jquery-20090913.ppt