Your SlideShare is downloading. ×
0
Ajax to the Moon Dave Johnson CTO and Co-founder Nitobi www.nitobi.com
Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance <...
Who I Am <ul><li>Nitobi Enterprise Ajax Podcast </li></ul><ul><li>Enterprise Ajax book (Prentice Hall) </li></ul><ul><li>b...
What Do I Do? <ul><li>Nitobi co-founder </li></ul><ul><li>Located in Vancouver, Canada </li></ul><ul><li>Ajax user-interfa...
 
Clients
Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance <...
Offline Ajax http://www.flickr.com/photos/natearcher/378519540/
Know your users
Why Offline <ul><li>Hard at work </li></ul><ul><li>Get on a plane </li></ul><ul><li>Keep on working </li></ul>
http://www.flickr.com/photos/plakboek/339017053/
Why Offline <ul><li>Hard at work </li></ul><ul><li>Get on a plane </li></ul><ul><li>Keep on working </li></ul><ul><li>Get ...
 
 
But Seriously <ul><li>Internet connections do not grow on trees </li></ul><ul><li>Try going to Sun HQ and getting on their...
How Does it Work? <ul><li>Work offline </li></ul><ul><li>Store data locally when browser is closed </li></ul><ul><li>Send ...
 
Storage <ul><li>Cookies </li></ul><ul><li>Firefox / Internet Explorer only </li></ul><ul><li>Flash </li></ul><ul><li>Insta...
Cookies <ul><li>4Kb of storage per domain </li></ul><ul><li>Easily deleted – probably suspected as Spyware </li></ul>
Firefox 2.0 Offline Storage <ul><li>Cookies on steroids </li></ul><ul><li>Data not available across sessions </li></ul><ul...
<ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script type=”text/javascript”> </li></ul><ul><li>function saveS...
Internet Explorer userData Behavior <ul><li>Access data across sessions </li></ul><ul><li>128Kb limit for Internet (512Kb ...
<ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script type=”text/javascript”> </li></ul><ul><li>function save(...
Flash SharedObject Storage <ul><li>Access data across sessions </li></ul><ul><li>User definable storage limit (default of ...
Flash Movie <ul><li>import  flash.external.ExternalInterface; </li></ul><ul><li>function  saveAttribute(datastore, paramna...
<ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script> </li></ul><ul><li>function thisMovie(movieName) { </li>...
<ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script> </li></ul><ul><li>function thisMovie(movieName) { </li>...
Apollo <ul><li>Adobe’s new runtime – currently Alpha </li></ul><ul><li>Offline capable, runs from your computer </li></ul>...
Web Proxy <ul><li>Proxy auto-config – browser proxy settings </li></ul><ul><li>JavaScript file with  FindProxyForURL </li>...
Salesforce.com Local Proxy
Whole Hog <ul><li>Web server </li></ul><ul><li>Database </li></ul><ul><li>Run locally </li></ul><ul><li>Zimbra uses this a...
Issues <ul><li>Performance </li></ul><ul><li>Concurrency </li></ul><ul><ul><li>Your own data or shared? </li></ul></ul><ul...
Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance <...
Pushing Ajax http://www.flickr.com/photos/vidiot/69075298/
Watch out for your thumb
Why Push? <ul><li>Keep client up to date </li></ul><ul><li>Collaboration </li></ul><ul><ul><li>Documents </li></ul></ul><u...
How Does it Work? Big scary Internet Innocent MySpace user MySpace Evil Empire TM
Polling <ul><li>Means to the same end </li></ul><ul><li>Easy to build </li></ul><ul><li>Request update from server every N...
http://www.flickr.com/photos/roadhunter/68017710/
How Does it Work? Big scary Internet Innocent MySpace user MySpace Evil Empire TM thumb twiddling …
Push <ul><li>Keep connection to server open </li></ul><ul><li>Server writes to stream when ready </li></ul><ul><li>Support...
http://www.flickr.com/photos/rev_bri/112249215/
Asynchronous Servlets <ul><li>Sun – Grizzly HTTP Connector </li></ul><ul><li>BEA –  AbstractAsyncServlet </li></ul><ul><li...
Cometd / Bayeux <ul><li>Cometd reference implementation </li></ul><ul><li>Bayeux pub/sub on top of Comet </li></ul><ul><ul...
DEMO <ul><li>http://localhost:8080/examples/magnets/ </li></ul>
Piggyback <ul><li>The middle of the road </li></ul><ul><li>Send data to client with any other responses </li></ul>
Other Approaches to Push <ul><li>LiveCycle Data Services </li></ul><ul><li>LightStreamer </li></ul>
Issues <ul><li>Server load </li></ul><ul><li>Internet Explorer </li></ul>
Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance <...
Ajax Performance http://www.flickr.com/photos/edfladung/451378444/ Ajax Performance
Ask questions first, optimize second
What is the Bottleneck? <ul><li>Situation dependent </li></ul><ul><li>How much data? </li></ul><ul><li>What type of data? ...
Lifecycle
Data Formats <ul><li>XML </li></ul><ul><ul><li><xml>You know this</xml> </li></ul></ul><ul><li>JSON </li></ul><ul><ul><li>...
Server <ul><li>HTML </li></ul><ul><ul><li>Whatever you use today </li></ul></ul><ul><li>XML </li></ul><ul><ul><li>Standard...
Bandwidth <ul><li>HTML </li></ul><ul><ul><li><div style=“color: red;”>Napoleon</div> </li></ul></ul><ul><li>XML </li></ul>...
JavaScript <ul><li>HTML </li></ul><ul><ul><li>Nothing to do </li></ul></ul><ul><li>XML </li></ul><ul><ul><li>Transform wit...
Internet Explorer
Firefox
http://www.jamesward.org/census/ Firefox Internet Explorer
XSLT Cross Browser Performance
Don’t Lose your Keys <ul><li><xsl:key name=“sales-by-customer” match=“customer” use=“@name” /> </li></ul><ul><li><xsl:valu...
XSLT Performance
JSON with Padding (JSONP) <ul><li>Most apps use XHR </li></ul><ul><li>Using XHR for JSON necessitates  eval() </li></ul><u...
The Fast, Server Dependent Way <ul><li>function  getPostsSi() { </li></ul><ul><li>var  elem = document.createElement(&quot...
The Slow, Server Agnostic Way <ul><li>function  getPostsXhr() { </li></ul><ul><li>var  xhr =  new  nitobi.ajax.HttpRequest...
HTML DOM <ul><li>HTML </li></ul><ul><ul><li>$(“myNode”).innerHTML = “<div>Napoleon</div>”; </li></ul></ul><ul><li>XML </li...
General DOM Function
Most Wanted <ul><li>innerHTML – consider HTML tags, floats, events </li></ul><ul><li>offsetTop / Left </li></ul><ul><li>ge...
Watch Out for Memory Leaks <ul><li>Circular loops between the DOM and JavaScript </li></ul><ul><li>Use Drip to find them <...
JavaScript Compression <ul><li>Removing comments </li></ul><ul><li>Removing whitespace </li></ul><ul><li>Removing new-line...
Simple Example var  _a =  function (a){ var  b=0; var  c=a.length; for ( var  d=0;d<c;d++){b+=a[d];} return  b/c;} var   c...
Rhino Minification / Obfuscation <ul><li><target  </li></ul><ul><li>name=&quot;obfuscateJS&quot;  </li></ul><ul><li>descri...
Compression <ul><li>Request </li></ul><ul><ul><li>Accept-Encoding: gzip,deflate </li></ul></ul><ul><li>Response </li></ul>...
Apache Compression <ul><li># Compress everything unless excluded below. </li></ul><ul><li>SetOutputFilter DEFLATE </li></u...
How Small is It? Size (Kb) Original   9.3 Minify   3.9   GZip / Deflate   2.8 Minify + GZip / Deflate   1.3   Size Reducti...
Content Merging <ul><li>Reduce download overhead by merging resources </li></ul><ul><ul><li>JavaScript </li></ul></ul><ul>...
Image Merging
Image Merging <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><style type=&quot;text/css&quot; media=&quot;scree...
Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance <...
Summary <ul><li>“ Work Offline” – know your users </li></ul><ul><ul><li>Browser specific, Flash or Install </li></ul></ul>...
Q&A <ul><li>Dave Johnson </li></ul><ul><li>www.nitobi.com </li></ul><ul><li>[email_address] </li></ul><ul><li>http://blogs...
Upcoming SlideShare
Loading in...5
×

Ajax to the Moon

3,378

Published on

CommunityOne presentation about offline Ajax, Ajax push, and Ajax performance issues.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,378
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
184
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Remove technical session reference…are we sure we have to use the J1 template?
  • Transcript of "Ajax to the Moon"

    1. 1. Ajax to the Moon Dave Johnson CTO and Co-founder Nitobi www.nitobi.com
    2. 2. Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance </li></ul><ul><li>Summary </li></ul>
    3. 3. Who I Am <ul><li>Nitobi Enterprise Ajax Podcast </li></ul><ul><li>Enterprise Ajax book (Prentice Hall) </li></ul><ul><li>blogs.nitobi.com/dave </li></ul>
    4. 4. What Do I Do? <ul><li>Nitobi co-founder </li></ul><ul><li>Located in Vancouver, Canada </li></ul><ul><li>Ajax user-interface components for the enterprise </li></ul>
    5. 6. Clients
    6. 7. Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance </li></ul><ul><li>Summary </li></ul>
    7. 8. Offline Ajax http://www.flickr.com/photos/natearcher/378519540/
    8. 9. Know your users
    9. 10. Why Offline <ul><li>Hard at work </li></ul><ul><li>Get on a plane </li></ul><ul><li>Keep on working </li></ul>
    10. 11. http://www.flickr.com/photos/plakboek/339017053/
    11. 12. Why Offline <ul><li>Hard at work </li></ul><ul><li>Get on a plane </li></ul><ul><li>Keep on working </li></ul><ul><li>Get Internet connection and sync data </li></ul><ul><li>More common than you may think! </li></ul>
    12. 15. But Seriously <ul><li>Internet connections do not grow on trees </li></ul><ul><li>Try going to Sun HQ and getting on their network! </li></ul>
    13. 16. How Does it Work? <ul><li>Work offline </li></ul><ul><li>Store data locally when browser is closed </li></ul><ul><li>Send data back to server when connected </li></ul>
    14. 18. Storage <ul><li>Cookies </li></ul><ul><li>Firefox / Internet Explorer only </li></ul><ul><li>Flash </li></ul><ul><li>Install software </li></ul>
    15. 19. Cookies <ul><li>4Kb of storage per domain </li></ul><ul><li>Easily deleted – probably suspected as Spyware </li></ul>
    16. 20. Firefox 2.0 Offline Storage <ul><li>Cookies on steroids </li></ul><ul><li>Data not available across sessions </li></ul><ul><li>5Mb of storage by default </li></ul><ul><li>A bit buggy at the moment but Firefox 3 should have global storage across sessions </li></ul>
    17. 21. <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script type=”text/javascript”> </li></ul><ul><li>function saveSession(myparam,myvalue) { </li></ul><ul><li>// will save the attribute myparam with value myvalue </li></ul><ul><li>sessionStorage[myparam] = myvalue; </li></ul><ul><li>} </li></ul><ul><li>function loadSession(myparam) { </li></ul><ul><li>// will retrieve myparam from sessionStorage </li></ul><ul><li>var myresult = sessionStorage[myparam]; </li></ul><ul><li>return myresult; </li></ul><ul><li>} </li></ul><ul><li></script> </li></ul><ul><li></head> </li></ul><ul><li><body> </li></ul><ul><li><form id=&quot;myform&quot; name=&quot;myform&quot;> </li></ul><ul><li><input type=&quot;text&quot; id=&quot;myvalue&quot; name=&quot;myvalue&quot;> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Save&quot; </li></ul><ul><li>onclick=&quot;saveSession('myattribute',myform.myvalue.value)&quot;> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Load&quot; </li></ul><ul><li>onclick=&quot;alert(loadSession('myattribute'))&quot;> </li></ul><ul><li></form> </li></ul><ul><li></body> </li></ul><ul><li></html> </li></ul>
    18. 22. Internet Explorer userData Behavior <ul><li>Access data across sessions </li></ul><ul><li>128Kb limit for Internet (512Kb for Intranet) </li></ul><ul><li>Relies on Internet Explorer Behaviors </li></ul><ul><li>What about HTML Applications? </li></ul>
    19. 23. <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script type=”text/javascript”> </li></ul><ul><li>function save(myparam,myvalue) { </li></ul><ul><li>$(“storageInput”).setAttribute(myparam, myvalue).save(&quot;mydata&quot;); </li></ul><ul><li>} </li></ul><ul><li>function load(myparam) { </li></ul><ul><li>return $(“storageInput”).load(&quot;mydata&quot;).getAttribute(myparam); </li></ul><ul><li>} </li></ul><ul><li></script> </li></ul><ul><li><style> </li></ul><ul><li>.storage { </li></ul><ul><li>behavior:url(#default#userData); </li></ul><ul><li>display:none; </li></ul><ul><li>} </li></ul><ul><li></style> </li></ul><ul><li></head> </li></ul><ul><li><body> </li></ul><ul><li><form id=&quot;myform&quot; name=&quot;myform&quot;> </li></ul><ul><li><input type=&quot;text&quot; id=&quot;myvalue&quot; name=&quot;myvalue&quot;> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Save&quot; onclick=&quot;save('myattr',myform.myvalue.value)&quot;> </li></ul><ul><li><input type=&quot;button&quot; value=&quot;Load&quot; onclick=&quot;alert(load('myattribute'))&quot;> </li></ul><ul><li><div id=”storageInput” class=”storage”></div> </li></ul><ul><li></form> </li></ul><ul><li></body> </li></ul><ul><li></html> </li></ul>
    20. 24. Flash SharedObject Storage <ul><li>Access data across sessions </li></ul><ul><li>User definable storage limit (default of 100Kb) </li></ul><ul><li>Back to Flash 6 (98% adoption) </li></ul>
    21. 25. Flash Movie <ul><li>import flash.external.ExternalInterface; </li></ul><ul><li>function saveAttribute(datastore, paramname, paramvalue) { </li></ul><ul><li>mySharedObject = SharedObject.getLocal(datastore); </li></ul><ul><li>mySharedObject.data[paramname] = paramvalue; </li></ul><ul><li>mySharedObject.flush(); </li></ul><ul><li>} </li></ul><ul><li>function loadAttribute(datastore,paramname) { </li></ul><ul><li>return SharedObject.getLocal(datastore).data[paramname]; </li></ul><ul><li>} </li></ul><ul><li>ExternalInterface.addCallback(&quot; saveAttribute &quot;, this, saveAttribute); </li></ul><ul><li>ExternalInterface.addCallback(&quot; loadAttribute &quot;, this, loadAttribute); </li></ul>
    22. 26. <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script> </li></ul><ul><li>function thisMovie(movieName) { </li></ul><ul><li>if (navigator.appName.indexOf(&quot;Microsoft&quot;) != -1) </li></ul><ul><li>return window[movieName]; </li></ul><ul><li>else </li></ul><ul><li>return document[movieName]; </li></ul><ul><li>} </li></ul><ul><li>function saveData(store, param, pvalue) { </li></ul><ul><li>thisMovie(‘myStorage’).saveAttribute(store,param,pvalue); </li></ul><ul><li>} </li></ul><ul><li>function loadData(store, param) { </li></ul><ul><li>return(thisMovie(‘myStorage’).loadAttribute(store,param)); </li></ul><ul><li>} </li></ul><ul><li></script> </li></ul><ul><li></head> </li></ul><ul><li><body> </li></ul><ul><li><object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000“ </li></ul><ul><li>codebase=&quot;…&quot; </li></ul><ul><li>width=&quot;1&quot; height=&quot;1&quot; id=&quot;myStorage&quot; align=&quot;middle&quot;> </li></ul><ul><li><param name=&quot;movie&quot; value=&quot;localstore.swf&quot; /> </li></ul><ul><li><param nam=&quot;allowScriptAccess&quot; value=&quot;always&quot;> </li></ul><ul><li><embed src=&quot;localstore.swf&quot; allowScriptAccess=&quot;always&quot; width=&quot;1&quot; height=&quot;1&quot; name=&quot;myStorage“ </li></ul><ul><li>type=&quot;application/x-shockwave-flash&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; /> </li></ul><ul><li></object> </li></ul><ul><li></body> </li></ul><ul><li></html> </li></ul>
    23. 27. <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><script> </li></ul><ul><li>function thisMovie(movieName) { </li></ul><ul><li>if (navigator.appName.indexOf(&quot;Microsoft&quot;) != -1) </li></ul><ul><li>return window[movieName]; </li></ul><ul><li>else </li></ul><ul><li>return document[movieName]; </li></ul><ul><li>} </li></ul><ul><li>function saveData(store, param, pvalue) { </li></ul><ul><li>thisMovie(‘myStorage’).saveAttribute(store,param,pvalue); </li></ul><ul><li>} </li></ul><ul><li>function loadData(store, param) { </li></ul><ul><li>return(thisMovie(‘myStorage’).loadAttribute(store,param)); </li></ul><ul><li>} </li></ul><ul><li></script> </li></ul><ul><li></head> </li></ul><ul><li><body> </li></ul><ul><li><object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000“ </li></ul><ul><li>codebase=&quot;…&quot; </li></ul><ul><li>width=&quot;1&quot; height=&quot;1&quot; id=&quot;myStorage&quot; align=&quot;middle&quot;> </li></ul><ul><li><param name=&quot;movie&quot; value=&quot;localstore.swf&quot; /> </li></ul><ul><li><param nam=&quot;allowScriptAccess&quot; value=&quot;always&quot;> </li></ul><ul><li><embed src=&quot;localstore.swf&quot; allowScriptAccess=&quot;always&quot; width=&quot;1&quot; height=&quot;1&quot; name=&quot;myStorage“ </li></ul><ul><li>type=&quot;application/x-shockwave-flash&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; /> </li></ul><ul><li></object> </li></ul><ul><li></body> </li></ul><ul><li></html> </li></ul>
    24. 28. Apollo <ul><li>Adobe’s new runtime – currently Alpha </li></ul><ul><li>Offline capable, runs from your computer </li></ul><ul><li>A lot more than just offline! </li></ul><ul><ul><li>Flex + WebKit (i.e. Safari) in one </li></ul></ul>
    25. 29. Web Proxy <ul><li>Proxy auto-config – browser proxy settings </li></ul><ul><li>JavaScript file with FindProxyForURL </li></ul><ul><li>Forward requests to a local proxy for interested domains </li></ul><ul><li>Used by the Dojo Toolkit </li></ul>
    26. 30. Salesforce.com Local Proxy
    27. 31. Whole Hog <ul><li>Web server </li></ul><ul><li>Database </li></ul><ul><li>Run locally </li></ul><ul><li>Zimbra uses this approach </li></ul>
    28. 32. Issues <ul><li>Performance </li></ul><ul><li>Concurrency </li></ul><ul><ul><li>Your own data or shared? </li></ul></ul><ul><li>End user requirements </li></ul><ul><ul><li>Are they a captive user? </li></ul></ul><ul><li>Penetration </li></ul>
    29. 33. Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
    30. 34. Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
    31. 35. Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
    32. 36. Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
    33. 37. Proxy Whole Hog Flash Browser Specific Cookies Concurrency Performance End user reqs / Penetration
    34. 38. Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance </li></ul><ul><li>Summary </li></ul>
    35. 39. Pushing Ajax http://www.flickr.com/photos/vidiot/69075298/
    36. 40. Watch out for your thumb
    37. 41. Why Push? <ul><li>Keep client up to date </li></ul><ul><li>Collaboration </li></ul><ul><ul><li>Documents </li></ul></ul><ul><ul><li>Communication </li></ul></ul><ul><li>Time sensitive data </li></ul>
    38. 42. How Does it Work? Big scary Internet Innocent MySpace user MySpace Evil Empire TM
    39. 43. Polling <ul><li>Means to the same end </li></ul><ul><li>Easy to build </li></ul><ul><li>Request update from server every N seconds </li></ul><ul><li>Support thousands of concurrent users? </li></ul><ul><li>users / pollTime = requests per second </li></ul>
    40. 44. http://www.flickr.com/photos/roadhunter/68017710/
    41. 45. How Does it Work? Big scary Internet Innocent MySpace user MySpace Evil Empire TM thumb twiddling …
    42. 46. Push <ul><li>Keep connection to server open </li></ul><ul><li>Server writes to stream when ready </li></ul><ul><li>Support thousands of concurrent users? </li></ul><ul><li>numConnections ≡ numServerThreads </li></ul>
    43. 47. http://www.flickr.com/photos/rev_bri/112249215/
    44. 48. Asynchronous Servlets <ul><li>Sun – Grizzly HTTP Connector </li></ul><ul><li>BEA – AbstractAsyncServlet </li></ul><ul><li>Tomcat 6.x – CometServlet </li></ul><ul><li>Jetty – Continuations </li></ul><ul><li>No standards here </li></ul>
    45. 49. Cometd / Bayeux <ul><li>Cometd reference implementation </li></ul><ul><li>Bayeux pub/sub on top of Comet </li></ul><ul><ul><li>Think JMS for JavaScript </li></ul></ul>
    46. 50. DEMO <ul><li>http://localhost:8080/examples/magnets/ </li></ul>
    47. 51. Piggyback <ul><li>The middle of the road </li></ul><ul><li>Send data to client with any other responses </li></ul>
    48. 52. Other Approaches to Push <ul><li>LiveCycle Data Services </li></ul><ul><li>LightStreamer </li></ul>
    49. 53. Issues <ul><li>Server load </li></ul><ul><li>Internet Explorer </li></ul>
    50. 54. Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance </li></ul><ul><li>Summary </li></ul>
    51. 55. Ajax Performance http://www.flickr.com/photos/edfladung/451378444/ Ajax Performance
    52. 56. Ask questions first, optimize second
    53. 57. What is the Bottleneck? <ul><li>Situation dependent </li></ul><ul><li>How much data? </li></ul><ul><li>What type of data? </li></ul><ul><li>How many server hits? </li></ul><ul><li>What are the common workflows? </li></ul><ul><li>What browsers are you targeting? </li></ul><ul><li>What is the existing infrastructure? </li></ul>
    54. 58. Lifecycle
    55. 59. Data Formats <ul><li>XML </li></ul><ul><ul><li><xml>You know this</xml> </li></ul></ul><ul><li>JSON </li></ul><ul><ul><li>{“json”:[“maybe”,”you”,don’t”],”know”:”this”} </li></ul></ul><ul><li>HTML </li></ul><ul><ul><li><html>Looks familiar</html> </li></ul></ul><ul><li>Text </li></ul><ul><li>Images </li></ul>
    56. 60. Server <ul><li>HTML </li></ul><ul><ul><li>Whatever you use today </li></ul></ul><ul><li>XML </li></ul><ul><ul><li>Standard support for object serialization </li></ul></ul><ul><ul><li>Similar to HTML </li></ul></ul><ul><li>JSON </li></ul><ul><ul><li>Easy to add on </li></ul></ul>
    57. 61. Bandwidth <ul><li>HTML </li></ul><ul><ul><li><div style=“color: red;”>Napoleon</div> </li></ul></ul><ul><li>XML </li></ul><ul><ul><li><customer><name>Napoleon</name></customer> </li></ul></ul><ul><ul><li><c n=“Napoleon”/> </li></ul></ul><ul><li>JSON </li></ul><ul><ul><li>{“customer”:[{“Name”:”Napoleon”}]} </li></ul></ul><ul><ul><li>{“c”:[{“n”:”Napoleon”}]} </li></ul></ul><ul><li>Polling, code size etc </li></ul>
    58. 62. JavaScript <ul><li>HTML </li></ul><ul><ul><li>Nothing to do </li></ul></ul><ul><li>XML </li></ul><ul><ul><li>Transform with XSLT (browser dependent) </li></ul></ul><ul><ul><li>Iterate over XML DOM nodes and string build </li></ul></ul><ul><ul><li>Iterate over XML DOM nodes and create HTML DOM nodes </li></ul></ul><ul><li>JSON </li></ul><ul><ul><li>eval() the block of JSON to a JavaScript object </li></ul></ul><ul><ul><li>Transform with JSON Templates </li></ul></ul><ul><ul><li>Iterate through JavaScript arrays and string build </li></ul></ul><ul><ul><li>Iterate through JavaScript arrays and create HTML DOM nodes </li></ul></ul>
    59. 63. Internet Explorer
    60. 64. Firefox
    61. 65. http://www.jamesward.org/census/ Firefox Internet Explorer
    62. 66. XSLT Cross Browser Performance
    63. 67. Don’t Lose your Keys <ul><li><xsl:key name=“sales-by-customer” match=“customer” use=“@name” /> </li></ul><ul><li><xsl:value-of select=&quot;key(‘sales-by-customer', $CustomerName)&quot;> </li></ul>
    64. 68. XSLT Performance
    65. 69. JSON with Padding (JSONP) <ul><li>Most apps use XHR </li></ul><ul><li>Using XHR for JSON necessitates eval() </li></ul><ul><li>eval() is slow </li></ul><ul><li>Instead dynamically insert a <script> tag and have the returned JavaScript call a function … </li></ul><ul><li>http://localhost/javaone/ </li></ul>
    66. 70. The Fast, Server Dependent Way <ul><li>function getPostsSi() { </li></ul><ul><li>var elem = document.createElement(&quot;script&quot;); </li></ul><ul><li>elem.src = &quot;http://del.icio.us/feeds/json/davyjones? callback = buildHtml &quot;; </li></ul><ul><li>document.body.appendChild(elem); </li></ul><ul><li>} </li></ul><ul><li>function buildHtml (obj) { </li></ul><ul><li>var s = []; </li></ul><ul><li>for (var i=0; i<obj.length; i++) { </li></ul><ul><li>s.push(&quot;<div><a href='&quot;+obj[i].u+&quot;'>&quot; + obj[i].d + &quot;</a></div>&quot;); </li></ul><ul><li>} </li></ul><ul><li>$(&quot;container&quot;).innerHTML = s.join(&quot;&quot;); </li></ul><ul><li>} </li></ul>
    67. 71. The Slow, Server Agnostic Way <ul><li>function getPostsXhr() { </li></ul><ul><li>var xhr = new nitobi.ajax.HttpRequest(); </li></ul><ul><li>xhr.handler = &quot;http://localhost/feeds/json/davyjones&quot;; </li></ul><ul><li>xhr.onComplete.subscribe(xhrDataReady); </li></ul><ul><li>xhr.send(); </li></ul><ul><li>} </li></ul><ul><li>function xhrDataReady(evtArgs) { </li></ul><ul><li>var obj = eval(&quot;(&quot;+evtArgs+&quot;)&quot;); </li></ul><ul><li>buildHtml (obj); </li></ul><ul><li>} </li></ul>
    68. 72. HTML DOM <ul><li>HTML </li></ul><ul><ul><li>$(“myNode”).innerHTML = “<div>Napoleon</div>”; </li></ul></ul><ul><li>XML </li></ul><ul><ul><li>innerHTML </li></ul></ul><ul><ul><li>DOM manipulations </li></ul></ul><ul><ul><ul><li>createElement(“div”), appendChild(node), etc </li></ul></ul></ul><ul><li>JSON </li></ul><ul><ul><li>innerHTML </li></ul></ul><ul><ul><li>DOM manipulations </li></ul></ul><ul><li>Interactivity </li></ul>
    69. 73. General DOM Function
    70. 74. Most Wanted <ul><li>innerHTML – consider HTML tags, floats, events </li></ul><ul><li>offsetTop / Left </li></ul><ul><li>getBoundingClientRect / getBoxObjectFor </li></ul><ul><li>Stylesheets </li></ul>
    71. 75. Watch Out for Memory Leaks <ul><li>Circular loops between the DOM and JavaScript </li></ul><ul><li>Use Drip to find them </li></ul><script type=“text/javascript”> var domNode = $(“myDomNode”); domNode .foo = domNode ; </script> expando
    72. 76. JavaScript Compression <ul><li>Removing comments </li></ul><ul><li>Removing whitespace </li></ul><ul><li>Removing new-line characters </li></ul><ul><li>Replacing variables with shorter names </li></ul>
    73. 77. Simple Example var _a = function (a){ var b=0; var c=a.length; for ( var d=0;d<c;d++){b+=a[d];} return b/c;} var calcAverage =_a; /** * @private */ var _calcAverage = function(aNumber) { var nTotal = 0; var iLength = aNumber.length; for ( var iIndex = 0; i<iLength; i++) { nTotal += aNumber[iIndex]; } return nTotal/iLength; } /** * Calculates the average of an array of numbers. * @param {Array} Array of numbers to average. */ var calcAverage = _calcAverage;
    74. 78. Rhino Minification / Obfuscation <ul><li><target </li></ul><ul><li>name=&quot;obfuscateJS&quot; </li></ul><ul><li>description=&quot;compress and obfuscate code&quot;> </li></ul><ul><li><java </li></ul><ul><li>classname=&quot;org.mozilla.javascript.tools.shell.Main“ </li></ul><ul><li>dir=&quot;${basedir}uild hinoin&quot; </li></ul><ul><li>fork=&quot;true&quot; </li></ul><ul><li>output=&quot;${basedir}outputsrc_obfuscated.js&quot;> </li></ul><ul><li><arg line=&quot;-c ${basedir}inputsrc.js &quot; /> </li></ul><ul><li><classpath> </li></ul><ul><li><pathelement path=&quot;${basedir}uild hinoinjs.jar&quot; /> </li></ul><ul><li></classpath> </li></ul><ul><li></java> </li></ul><ul><li></target> </li></ul>
    75. 79. Compression <ul><li>Request </li></ul><ul><ul><li>Accept-Encoding: gzip,deflate </li></ul></ul><ul><li>Response </li></ul><ul><ul><li>Content-Encoding: gzip || deflate </li></ul></ul><ul><li>IIS and Apache dynamically GZip / Deflate content and cache it </li></ul><ul><li>All modern browsers support compressed content </li></ul><ul><ul><li>Internet Explorer 6 SP1 had some problems </li></ul></ul><ul><li>IE, Firefox, Opera accept compressed content _without_ Content-Encoding header </li></ul>
    76. 80. Apache Compression <ul><li># Compress everything unless excluded below. </li></ul><ul><li>SetOutputFilter DEFLATE </li></ul><ul><li>SetInputFilter DEFLATE </li></ul><ul><li>SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary </li></ul><ul><li>SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|rar)$ no-gzip dont-vary </li></ul><ul><li>SetEnvIfNoCase Request_URI .(?:pdf|avi|mov|mp3|rm)$ no-gzip dont-vary </li></ul><ul><li># Explicity compress certain file types </li></ul><ul><li>AddOutputFilterByType DEFLATE text/html text/plain text/xml </li></ul>
    77. 81. How Small is It? Size (Kb) Original 9.3 Minify 3.9 GZip / Deflate 2.8 Minify + GZip / Deflate 1.3 Size Reduction 86% Expected Results for JavaScript Compression
    78. 82. Content Merging <ul><li>Reduce download overhead by merging resources </li></ul><ul><ul><li>JavaScript </li></ul></ul><ul><ul><li>Cascading Stylesheets </li></ul></ul><ul><ul><li>Images </li></ul></ul><ul><li>Careful with caching though! </li></ul>
    79. 83. Image Merging
    80. 84. Image Merging <ul><li><html> </li></ul><ul><li><head> </li></ul><ul><li><style type=&quot;text/css&quot; media=&quot;screen&quot;> </li></ul><ul><li>.colour {clip: rect(0px 135px 125px 0px);} </li></ul><ul><li>.grayscale { </li></ul><ul><li>left:-135px; </li></ul><ul><li>clip: rect(0px 270px 125px 135px); </li></ul><ul><li>} </li></ul><ul><li>.grayscale, .colour { </li></ul><ul><li>position:absolute; </li></ul><ul><li>width: 270px;height: 125px; </li></ul><ul><li>background: url(images/nitobi.jpg); </li></ul><ul><li>} </li></ul><ul><li>.container { </li></ul><ul><li>height:125px;width:135px; </li></ul><ul><li>position:relative; </li></ul><ul><li>} </li></ul><ul><li></style> </li></ul><ul><li></head> </li></ul><ul><li><body> </li></ul><ul><li><div class=&quot;container&quot;><div class=&quot;colour&quot;></div></div> </li></ul><ul><li><div class=&quot;container&quot;><div class=&quot;grayscale&quot;></div></div> </li></ul><ul><li></body> </li></ul><ul><li></html> </li></ul>clip: rect(0px 135px 125px 0px); clip: rect(0px 270px 125px 135px); background: url(images/nitobi.jpg);
    81. 85. Agenda <ul><li>Who I Am </li></ul><ul><li>Offline Ajax </li></ul><ul><li>Pushing Ajax </li></ul><ul><li>Ajax Performance </li></ul><ul><li>Summary </li></ul>
    82. 86. Summary <ul><li>“ Work Offline” – know your users </li></ul><ul><ul><li>Browser specific, Flash or Install </li></ul></ul><ul><ul><li>Usability </li></ul></ul><ul><li>Push – watch out for your thumb </li></ul><ul><ul><li>Real-time collaboration </li></ul></ul><ul><ul><li>Usability </li></ul></ul><ul><li>Performance – ask questions first, optimize later </li></ul><ul><ul><li>Be careful but not too careful </li></ul></ul><ul><ul><li>Usability </li></ul></ul>
    83. 87. Q&A <ul><li>Dave Johnson </li></ul><ul><li>www.nitobi.com </li></ul><ul><li>[email_address] </li></ul><ul><li>http://blogs.nitobi.com/dave </li></ul>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×