410 likes | 602 Views
JavaScript Library Showdown. Rob Larsen 4.30.2009 drunkenfist.com | @ rob_react http://media.drunkenfist.com/downloads/libraries.ppt. Who is this Guy Anyway?. 10+ years HTML/CSS/JavaScript all day Principal Presentation Engineer at Cramer
E N D
JavaScript Library Showdown Rob Larsen 4.30.2009 drunkenfist.com | @rob_react http://media.drunkenfist.com/downloads/libraries.ppt
Who is this Guy Anyway? • 10+ years HTML/CSS/JavaScript all day • Principal Presentation Engineer at Cramer • PAST: AdvisorTech, Compete, Demandware, Boston's Weekly Dig, Gillette, Museum of Science, Boston, PC Connection, State Street, Webex
History • I remember when dHTML was “cool” document.all(“ftw”) document.layers[0]
History • And then it wasn’t (http://www.amazon.com/Macromedia-Flash-5-Upgrade-Windows/dp/B00004WG0L)
History • And then it was actually cool, but we stopped mentioning dHTML Photo by Martin Kliehm ( http://www.flickr.com/photos/martin-kliehm/536545606/ )
Perspective • Front end performance • Library agnostic
What Libraries? • “By the book” JavaScript • “What I Would Normally Do” (small library with basic x-browser features and nothing else) • Dojo • jQuery • Prototype/Scriptaculous • YUI
How Will They Be Compared? • Simple Tasks • Performance (Page render & execution) • Code Base • Documentation/Overall Presentation • Anecdotes
What Tasks? • Fire a function when the DOM is loaded • That function attaches a click event to an HTML element • When clicked, a function fires that: • Grabs an RSS feed from Reddit and writes it into a UL • Grabs a JSON feed from search.twitter.com and writes it into a UL • Creates an IMG, inserts it into the document and Fades it up from 0 opacity.
* • “Not Science” the numbers are for discussion, not for library turf wars • Get it done • Shallow, not deep • Obvious answers- didn’t phone a friend
Exciting? • Heck Yeah. Photo by ortizmj12 (http://www.flickr.com/photos/23912576@N05/2940137084/) Photo by laverrue (http://www.flickr.com/photos/23912576@N05/2940137084/)
HTML <html> <head> <title>JavaScript</title> <script type="text/javascript" src="scripts/base.js"></script> <style type="text/css" media="screen"> @import url("../_assets/styles/screen.css"); </style> </head> <body> <div id="container"> <h1>Tell me about <a href="http://www.google.com/search?q=javascript" id="make-it-so">JavaScript</a></h1> <div id="twitter"> <!—tweets go here--> </div> <div id="feed"> <!—reddit goes here--> </div> <div id="image"> <!--image goes here--> </div> </div> </body> </html>
Add Load Event/ Add Event JavaScript function init() { document.getElementById("make-it-so").addEventListener("click" , results, false); } window.addEventListener("DOMContentLoaded", init, false); Dojo dojo.addOnLoad( function() { dojo.connect(dojo.byId("make-it-so"), 'onclick', results) } ); jQuery $(document).ready( function() { $("#make-it-so").click(results); } );
Add Load Event/ Add Event JavaScript function init() { document.getElementById("make-it-so").addEventListener("click" , results, false); } window.addEventListener("DOMContentLoaded", init, false); Dojo dojo.addOnLoad( function() { dojo.connect(dojo.byId("make-it-so"), 'onclick', results) } ); jQuery $(document).ready( function() { $("#make-it-so").click(results); } );
Add Load Event/ Add Event Prototype document.observe("dom:loaded", function() { $("make-it-so").observe("click" , results, false); }); YUI function init() { YAHOO.util.Event.addListener(YAHOO.util.Dom.get("make-it-so"), "click", results, this); }; YAHOO.util.Event.onDOMReady(init);
Add Load Event/ Add Event WIWND //Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/ function init() { if (arguments.callee.done) return; arguments.callee.done = true; if (_timer) clearInterval(_timer); //demo addEvent(document.getElementById("make-it-so"), "click" , results ); //end demo }; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false); }; //http://javascript.nwbox.com/IEContentLoaded/ /*@cc_on @*/ /*@if (@_win32) (function () { try { document.documentElement.doScroll('left'); } catch (e) { setTimeout(arguments.callee, 50); return; } init(); })(); /*@end @*/ if (/WebKit/i.test(navigator.userAgent)) { // sniff var _timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { init(); // call the onload handler } }, 10); }; window.onload = init;
Get JSON JavaScript/WIWND var twitterJSON = document.createElement("script"); twitterJSON.type="text/javascript"; twitterJSON.src="http://search.twitter.com/search.json?callback=writeTwitterSearchResults&q=%23javascript&count=10"; document.body.appendChild(twitterJSON); Dojo dojo.xhrGet( { url: '../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10', handleAs: "json", load: function(responseObject, ioArgs) { writeTwitterSearchResults(responseObject) } }); jQuery $.getJSON("../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10", writeTwitterSearchResults );
Get JSON Prototype New Ajax.Request('../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10', { method:'get', requestHeaders: {Accept: 'application/json'}, onSuccess: function(transport){ var json = transport.responseText.evalJSON(true); writeTwitterSearchResults(json); } } ); YUI YAHOO.util.Get.script("http://search.twitter.com/search.json?callback=writeTwitterSearchResults&q=%23javascript&count=10");
XHR JavaScript getData : function() { var data = new XMLHttpRequest(); data.onreadystatechange = function(){ if ( data.readyState == 4 && data.responseXML != null) { reddit.parseIt(data.responseXML); } }; data.open("GET", "../feed.php?url=http://www.reddit.com/r/javascript/.rss", true); data.send(null); } Dojo dojo.xhrGet( { url: '../feed.php?url=http://www.reddit.com/r/javascript/.rss', handleAs: "xml", load: function(responseObject, ioArgs) { reddit(responseObject) } });
XHR jQuery $.get("../feed.php?url=http://www.reddit.com/r/javascript/.rss", reddit ); Prototype new Ajax.Request("../feed.php?url=http://www.reddit.com/r/javascript/.rss", { method: 'get', onSuccess: function(transport) { reddit(transport.responseXML) } }); YUI var callback = { success:reddit }; var request = YAHOO.util.Connect.asyncRequest('GET', "../feed.php?url=http://www.reddit.com/r/javascript/.rss", callback);
Remove Element JavaScript twitterDIV.removeChild(document.getElementById("twitter-list")); WIWND twitterDIV.innerHTML=""; Dojo dojo.destroy("twitter-list"); jQuery $("#twitter-list").remove(); Prototype $("twitter-list").remove(); YUI twitterDIV.removeChild(YAHOO.util.Dom.get("twitter-list"));
Add Element, Fade Up JavaScript var image = { insert : function(){ if (document.getElementById("fadeMe")) { document.getElementById("image").removeChild(document.getElementById("fadeMe")); } var newImage = document.createElement("img"); newImage.src= "/web/samples/presentation/_assets/images/javascript.jpg"; newImage.setAttribute("id","fadeMe"); newImage.style.opacity=0; document.getElementById("image").appendChild(newImage); image.fadeUp(); }, fadeUp : function() { var fadeImage = document.getElementById("fadeMe") if (fadeImage.style.opacity < 1 ) { fadeImage.style.opacity=parseFloat(fadeImage.style.opacity) + .05; var callback = function() { image.fadeUp(); } setTimeout(callback,50); } } }
Add Element, Fade Up Dojo var newImage = document.createElement("img"); newImage.src= "/web/samples/presentation/_assets/images/javascript.jpg"; newImage.setAttribute("id","fadeMe"); newImage.style.opacity=0; dojo.byId("image").appendChild(newImage); dojo.fadeIn({ node : "fadeMe" , duration : 3000 }).play(); jQuery $("#image").append("<img id='fadeMe' src='/web/samples/presentation/_assets/images/javascript.jpg' style='display:none' />"); $("#fadeMe").fadeIn("slow"); Prototype $("image").insert(new Element("img", {"src" : "/web/samples/presentation/_assets/images/javascript.jpg", "id" :"fadeMe", "style" : "display:none"})); $("fadeMe").appear({ duration: 3.0 });
Add Element, Fade Up WIWND var image = { insert : function(){ if ($("fadeMe")) { $("image").innerHTML=""; }; /*@cc_on /*@if (@_win32) var style= "filter:alpha(opacity=0)"; @else @*/ var style="opacity:0"; /*@end @*/ $("image").innerHTML="<img src='/web/samples/presentation/_assets/images/javascript.jpg' style='"+style+"' id='fadeMe' />"; image.fadeUp(0); }, fadeUp : function(count) { var fadeImage = $("fadeMe"); count = count + 5; if (count < 100 ) { /*@cc_on /*@if (@_win32) fadeImage.style.filter ="alpha(opacity="+ count +")"; @else @*/ fadeImage.style.opacity= (count/100); /*@end @*/ var callback = function() { image.fadeUp(count); } setTimeout(callback,50); } } };
Add Element, Fade Up YUI var image = { insert : function(){ if (YAHOO.util.Dom.get("fadeMe")) { YAHOO.util.Dom.get("image").removeChild(YAHOO.util.Dom.get("fadeMe")); } var newImage = document.createElement("img"); newImage.src= "/web/samples/presentation/_assets/images/javascript.jpg"; newImage.setAttribute("id","fadeMe"); newImage.style.opacity=0; YAHOO.util.Dom.get("image").appendChild(newImage); image.fadeUp(0); }, fadeUp : function(count) { var fadeImage = YAHOO.util.Dom.get("fadeMe") count = count + 5; if (count < 100 ) { /*@cc_on /*@if (@_win32) fadeImage.style.filter ="alpha(opacity="+ count +")"; @else @*/ fadeImage.style.opacity= (count/100); /*@end @*/ var callback = function() { image.fadeUp(count); } setTimeout(callback,50); } } }
Pure JavaScript (anecdotal) • The Good: • Light. Fast. Standards based • The Bad: • More verbose. API awkward? • The Ugly: • Doesn’t work in 65% of the browsers worldwide
WIWND(anecdotal) • The Good: • Light. Fast. Handles “big” x-browser stuff. Fun (for me) • The Bad: • Not clever / less convenient. • The Ugly: • Lots of heavy lifting. Lots.
Dojo (anecdotal) • The Good: • Easy to pick up. HTML to include GZipped/CDN version right on download page • The Bad: • Slower. No JSON+Callback functionality. Need to learn to think in “Dojo” • The Ugly: • Documentation
jQuery (anecdotal) • The Good: • Easy to pick up. Fast, succinct code. Chaining is fun. Solid documentation. • The Bad: • No JSON+Callback functionality. Need to learn to think in “jQuery.” CDN link not promoted. • The Ugly:
Prototype/Scriptaculous (anecdotal) • The Good: • Feels more like JavaScript. Deep. • The Bad: • No JSON+Callback functionality. Promoted code is not minified. Slowest of the libraries. • The Ugly: • “Blototype.” Reading documentation was like being punched in the face.
YUI (anecdotal) • The Good: • Fast. Incredible documentation. CDN + single file functionality. Deep bench of advanced functionality. JSON+Callback functionality. • The Bad: • Limited, generic effects. Leaves more basic work than other libraries. • The Ugly: • Code.is.Awkward.To.Me()
The Results • If forced (for public consumption) • jQuery • If forced (the app division) • YUI • If forced (the Palm Pre/webOS edition) • Prototype