5. 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
6. Why focus on JavaScript? AOL eBay Facebook MySpace Wikipedia Yahoo! YouTube
7. scripts block <script src="A.js"> blocks parallel downloads and rendering 7 secs: IE 8, FF 3.5, Chr 2, Saf 4 9 secs: IE 6-7, FF 3.0, Chr 1, Op 9-10, Saf 3
8. MSN.com: parallel scripts 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
9. Loading Scripts Without Blocking XHR Eval XHR Injection Script in Iframe Script DOM Element Script Defer document.write Script Tag
10. 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('');
11. 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
12.
13. 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
14. 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
15. 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.write s must be in same script block
17. Load Scripts Without Blocking * Only other document.write scripts are downloaded in parallel (in the same script block).
18. 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 order no order no busy show busy show busy no busy preserve order
22. Loading Scripts Without Blocking * Only other document.write scripts are downloaded in parallel (in the same script block). !IE
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36. 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
46. performance analyzers (HPWS) YSlow Page Speed Pagetest VRTA neXpert combine JS & CSS X X X use CSS sprites X X use a CDN X X set Expires in the future X X X X X gzip text responses X X X X X put CSS at the top X X put JS at the bottom X avoid CSS expressions X X make JS & CSS external reduce DNS lookups X X minify JS X X X avoid redirects X X X X remove dupe scripts X remove ETags X X X
47. performance analyzers (EFWS) YSlow Page Speed Pagetest VRTA neXpert don't block UI thread split JS payload X load scripts async X inline JS b4 stylesheet X write efficient JS min. uncompressed size optimize images X X shard domains X X flush the document avoid iframes simplify CSS selectors X X
48. performance analyzers (other) YSlow Page Speed Pagetest VRTA neXpert use persistent conns X X X reduce cookies 2.0 X X X avoid net congestion X increase MTU, TCP win X avoid server congestion X remove unused CSS X specify image dims X use GET for Ajax 2.0 reduce DOM elements 2.0 avoid 404 errors 2.0 avoid Alpha filters 2.0 don't scale images 2.0 X optimize favicon 2.0
Data source: Steve Souders Tested on IE6 on Comcast cable modem (~5 mbps) medium powered PC, April 2008.
photo courtesy of Vicki & Chuck Rogers: http://www.flickr.com/photos/two-wrongs/205467442/
Data Source: Steve Souders aol 76% ebay 45% facebook 41% google 42% live search 9% msn 37% myspace 37% yahoo 45% youtube 60% wikipedia 26% average 42%
Of the ten top sites, MSN.com (Script DOM Element), Live Search (Script in Iframe), and Yahoo (Script DOM Element) use advanced script loading techniques.
All of these allow for parallel downloads, but none of them allow for parallel JS execution – that's not possible (currently, WebKit is doing some stuff on that).
Audio (IE &quot;click&quot;) is another busy indicator. Delayed rendering and delayed onload (&quot;done&quot;) are other busy indicators. Sometimes busy indicators are bad, sometimes good.
Data source: Steve Souders
I'll do JavaScript and PHP implementations of this logic soon.
Data source: Steve Souders
putting code in the script block doesn't work in any browser; you have to add stuff to the external script this doesn't load asynchronously
Newer browsers (IE8, Saf4, Chr2) work, but mainstream browsers need a workaround.
Newer browsers (IE8, Saf4, Chr2) work, but mainstream browsers need a workaround.
loadInterval is 420 ms
esp. good when your HTML document takes more than 10-20%, and when users have high latency.