Steve Souders [email protected] Even Faster Web Sites Disclaimer: This content does not...
-
Upload
megan-black -
Category
Documents
-
view
235 -
download
2
Transcript of Steve Souders [email protected] Even Faster Web Sites Disclaimer: This content does not...
![Page 1: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/1.jpg)
Steve [email protected]
http://stevesouders.com/docs/google-20090305.ppt
Even Faster Web Sites
Disclaimer: This content does not necessarily reflect the opinions of my employer.
![Page 2: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/2.jpg)
14 Rules1. Make fewer HTTP
requests2. Use a CDN3. Add an Expires header4. Gzip components5. Put stylesheets at the
top6. Put scripts at the
bottom7. Avoid CSS expressions8. Make JS and CSS
external9. Reduce DNS lookups10.Minify JS11.Avoid redirects12.Remove duplicate
scripts13.Configure ETags14.Make AJAX cacheable
![Page 3: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/3.jpg)
![Page 4: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/4.jpg)
![Page 5: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/5.jpg)
![Page 6: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/6.jpg)
![Page 7: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/7.jpg)
![Page 8: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/8.jpg)
Even Faster Web Sites
Split the initial payloadLoad scripts without
blockingCouple asynchronous scripts
Don't scatter inline scriptsSplit the dominant
domainFlush the document early
Use iframes sparingly
Simplify CSS Selectors
O'Reilly, June 2009
Ajax performance (Doug Crockford)
Writing efficient JavaScript (Nicholas Zakas)
Creating responsive web apps (Ben Galbraith, Dion Almaer)
Comet (Dylan Schiemann)Beyond Gzipping (Tony
Gentilcore)Optimize Images (Stoyan
Stefanov, Nicole Sullivan)
![Page 9: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/9.jpg)
AOLeBayFacebookMySpaceWikipediaYahoo!
Why focus on JavaScript?
YouTube
![Page 10: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/10.jpg)
Scripts Block
<script src="A.js"> blocks parallel downloads and rendering
http://stevesouders.com/cuzillion/?ex=10008
![Page 11: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/11.jpg)
MSNScripts 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
![Page 12: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/12.jpg)
Advanced Script Loading
XHR Eval
XHR Injection
Script in Iframe
Script DOM Element
Script Defer
document.write Script Tag
![Page 13: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/13.jpg)
Summary of Traits
*Only other document.write scripts are downloaded in parallel (in the same script block).
![Page 14: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/14.jpg)
and the winner is...XHR EvalXHR InjectionScript in iframeScript DOM ElementScript Defer
Script DOM ElementScript Defer
Script DOM Element
Script DOM Element (FF)Script Defer (IE)
XHR EvalXHR InjectionScript in iframeScript DOM Element (IE)
XHR InjectionXHR EvalScript DOM Element (IE)
Managed XHR InjectionManaged XHR EvalScript DOM Element
Managed XHR InjectionManaged XHR Eval
Script DOM Element (FF)Script Defer (IE)Managed XHR EvalManaged XHR Injection
Script DOM Element (FF)Script Defer (IE)Managed XHR EvalManaged XHR Injection
different domains same domains
no order
preserve order
no order
no busyshow busy
show busyno busy
preserve order
![Page 15: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/15.jpg)
what about
inlined code that depends on the script?
![Page 16: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/16.jpg)
![Page 17: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/17.jpg)
synchronous JS example: menu.js
<script src="menu.js" type="text/javascript"></script>
<script type="text/javascript">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>
![Page 18: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/18.jpg)
asynchronous JS example: menu.js
<script type="text/javascript"> var domscript = document.createElement('script');domscript.src = "menu.js"; document.getElementsByTagName('head')
[0].appendChild(domscript);
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
![Page 19: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/19.jpg)
![Page 20: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/20.jpg)
baseline coupling results (not good)
* Scripts download in parallel regardless of the Defer attribute.
need a way to load scripts asynchronously AND preserve order
![Page 21: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/21.jpg)
coupling techniques
hardcoded callback
window onload
timer
script onload
degrading script tags
![Page 22: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/22.jpg)
technique 1: hardcoded callback
<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";document.getElementsByTagName('head')
[0].appendChild(domscript);</script>
init() is called from within menu.jsnot very flexibledoesn't work for 3rd party scripts
![Page 23: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/23.jpg)
technique 2: window onload<iframe src="menu.php" width=0 height=0 frameborder=0> </iframe><script type="text/javascript">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);}</script>
init() is called at window onloadmust use async technique that blocks
onload:Script in Iframe does this across most browsers
init() called later than necessary
![Page 24: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/24.jpg)
technique 3: timer<script type="text/javascript">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);</script>
load if interval too low, delay if too highslight increased maintenance – EFWS
![Page 25: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/25.jpg)
technique 4: 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() { domscript.onloadDone = true; init(); };domscript.onreadystatechange = function() { if ( "loaded" === domscript.readyState && ! domscript.onloadDone ) { domscript.onloadDone = true; init(); }}document.getElementsByTagName('head')[0].appendChild(domscript);</script>
pretty nice, more complicated
![Page 26: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/26.jpg)
John Resig's degrading script tags
<script src="menu-degrading.js" type="text/javascript">var aExamples = [['couple-normal.php', 'Normal Script Src'], ...];
function init() { EFWS.Menu.createMenu('examplesbtn', aExamples);}
init();</script>
cleanerclearersafer – inlined code not called if script
fails
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/
![Page 27: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/27.jpg)
technique 5: degrading script tags
<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-degrading.js";if ( -1 != navigator.userAgent.indexOf("Opera") ) { domscript.innerHTML = "init();";}else { domscript.text = "init();";}document.getElementsByTagName('head')[0].appendChild(domscript);</script>
elegant, flexible (cool!)not well knowndoesn't work for 3rd party scripts
(unless...)
![Page 28: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/28.jpg)
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
![Page 29: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/29.jpg)
multiple script example: menutier.js
<script src="menu.js" type="text/javascript"></script>
<script src="menutier.js" type="text/javascript"></script>
<script type="text/javascript">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);}</script>
![Page 30: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/30.jpg)
technique 1: managed XHR<script type="text/javascript">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);</script>
XHR Injection asynchronous technique does not preserve order – we have to add that
before
after
![Page 31: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/31.jpg)
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)
![Page 32: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/32.jpg)
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 order
non-blockingworks in all browserscouples with inlined
codeworks with scripts across domains
![Page 33: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/33.jpg)
technique 2: DOM Element and Doc Write
Firefox & Opera – use Script DOM Element
IE – use document.write Script Tag
Safari, Chrome – no benefit; rely on Safari 4 and Chrome 2
![Page 34: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/34.jpg)
EFWS.loadScriptsloadScripts: 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); }}
![Page 35: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/35.jpg)
coupling wrap-up
![Page 36: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/36.jpg)
case study: Google Analytics
recommended pattern:1
<script type="text/javascript">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"));
</script>
<script type="text/javascript">var pageTracker = _gat._getTracker("UA-xxxxxx-x");pageTracker._trackPageview();</script>
document.write Script Tag approach blocks other resources
1http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55488
![Page 37: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/37.jpg)
case study: Google Analytics
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 approachtimer coupling technique (script onload
better)1http://docs.dojocampus.org/dojox/analytics/Urchin
![Page 38: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/38.jpg)
iframes: most expensive DOM element
load 100 empty elements of each type
tested in all major browsers1
1IE 6, 7, 8; FF 2, 3.0, 3.1b2; Safari 3.2, 4; Opera 9.63, 10; Chrome 1.0, 2.0
![Page 39: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/39.jpg)
iframes block onload
parent's onload doesn't fire until iframe and all its components are downloaded
workaround for Safari and Chrome: set iframe src in JavaScript
<iframe id=iframe1 src=""></iframe><script type="text/javascript">document.getElementById('iframe1').src="url";</script>
![Page 40: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/40.jpg)
scripts block iframe
no surprise – scripts in the parent block the iframe from loading
IE
Firefox
Safari Chrome
Opera
script
script
script
![Page 41: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/41.jpg)
stylesheets block iframe (IE, FF)
surprise – stylesheets in the parent block the iframe or its resources in IE & Firefox
IE
Firefox
Safari Chrome
Opera
stylesheet
stylesheet
stylesheet
![Page 42: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/42.jpg)
stylesheets after iframe still block (FF)
surprise – even moving the stylesheet after the iframe still causes the iframe's resources to be blocked in Firefox
IE
Firefox
Safari Chrome
Opera
stylesheet
stylesheet
stylesheet
![Page 43: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/43.jpg)
iframes: no free connections
iframe shares connection pool with parent (here – 2 connections per server in IE 7)
iframe
parent
![Page 44: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/44.jpg)
flush the document early
gotchas:– PHP output_buffering – ob_flush()– Transfer-Encoding: chunked– gzip – Apache's DeflateBufferSize before
2.2.8– proxies and anti-virus software– browsers – Safari (1K), Chrome (2K)
htmlimageimagescript
htmlimageimagescript
![Page 45: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/45.jpg)
flushing and domain blocking
you might need to move flushed resources to a domain different from the HTML doc
htmlimageimagescript
htmlimageimagescript
googleimageimagescriptimage204
![Page 46: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/46.jpg)
Takeaways
focus on the frontend
run YSlow: http://developer.yahoo.com/yslow
this year's focus: JavaScriptSplit the Initial PayloadLoad Scripts without BlockingDon't Scatter Inline Scripts
speed matters
![Page 47: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/47.jpg)
Impact on Revenue
Google:
Yahoo:
Amazon:
1 http://home.blarg.net/~glinden/StanfordDataMining.2006-11-29.ppt2 http://www.slideshare.net/stoyan/yslow-20-presentation
+500 ms -20% traffic1
+400 ms -5-9% full-page traffic2
+100 ms -1% sales1
![Page 48: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/48.jpg)
Cost Savings
hardware – reduced load
bandwidth – reduced response size
http://billwscott.com/share/presentations/2008/stanford/HPWP-RealWorld.pdf
![Page 49: Steve Souders souders@google.com Even Faster Web Sites Disclaimer: This content does not necessarily reflect.](https://reader033.fdocuments.in/reader033/viewer/2022061306/55146602550346284e8b5b33/html5/thumbnails/49.jpg)
if you wantbetter user experiencemore revenuereduced operating expenses
the strategy is clear
Even Faster Web Sites